1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 28a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project 48a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkXfermode.h" 10c524e98f1edf06b53e65543f5f28217fa13b7aa9commit-bot@chromium.org#include "SkXfermode_opts_SSE2.h" 11df187c7eb27d7616b75d91f3329deb97c4cd6de2commit-bot@chromium.org#include "SkXfermode_proccoeff.h" 126cbf18c70bf99f58b2bb1c49cdf8d41be561fee4mtklein#include "Sk4px.h" 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorPriv.h" 1497de357270e54be53acb17e1cb4b4d5e25bacc01commit-bot@chromium.org#include "SkLazyPtr.h" 154b163ed2c22facbe8891616874ae07ba7827d9c9reed@google.com#include "SkMathPriv.h" 16f92ace90d89cc99b34162dda26be564e34ca80efreed#include "SkPMFloat.h" 17140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org#include "SkReadBuffer.h" 18b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com#include "SkString.h" 19cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org#include "SkUtilsArm.h" 20140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org#include "SkWriteBuffer.h" 21cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org 2204d24a3f86b6f2382e5c6ffaf161ffc734a4d02amtklein// When implemented, the Sk4f and Sk4px xfermodes beat src/opts/SkXfermodes_opts_SSE2's. 2304d24a3f86b6f2382e5c6ffaf161ffc734a4d02amtklein// When implemented, the Sk4px, but not Sk4f, xfermodes beat src/opts/SkXfermodes_arm_neon's. 243006b2e013f29f8b00f6afabbe5b2a8737840bc6reed#if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2 2504d24a3f86b6f2382e5c6ffaf161ffc734a4d02amtklein #define SK_4F_XFERMODES_ARE_FAST 2604d24a3f86b6f2382e5c6ffaf161ffc734a4d02amtklein #define SK_4PX_XFERMODES_ARE_FAST 2704d24a3f86b6f2382e5c6ffaf161ffc734a4d02amtklein#elif defined(SK_ARM_HAS_NEON) 2804d24a3f86b6f2382e5c6ffaf161ffc734a4d02amtklein #define SK_4PX_XFERMODES_ARE_FAST 293006b2e013f29f8b00f6afabbe5b2a8737840bc6reed#endif 30f92ace90d89cc99b34162dda26be564e34ca80efreed 31cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org#if !SK_ARM_NEON_IS_NONE 3204d24a3f86b6f2382e5c6ffaf161ffc734a4d02amtklein #include "SkXfermode_opts_arm_neon.h" 33cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org#endif 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkAlphaMulAlpha(a, b) SkMulDiv255Round(a, b) 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 37da94699149a40a90731425766d3b994e34c5ba26deanm@chromium.orgstatic inline unsigned saturated_add(unsigned a, unsigned b) { 38543ed9352c7dfd93071c08b14930cca2e82a08d4reed@android.com SkASSERT(a <= 255); 39543ed9352c7dfd93071c08b14930cca2e82a08d4reed@android.com SkASSERT(b <= 255); 40543ed9352c7dfd93071c08b14930cca2e82a08d4reed@android.com unsigned sum = a + b; 41543ed9352c7dfd93071c08b14930cca2e82a08d4reed@android.com if (sum > 255) { 42543ed9352c7dfd93071c08b14930cca2e82a08d4reed@android.com sum = 255; 43543ed9352c7dfd93071c08b14930cca2e82a08d4reed@android.com } 44543ed9352c7dfd93071c08b14930cca2e82a08d4reed@android.com return sum; 45543ed9352c7dfd93071c08b14930cca2e82a08d4reed@android.com} 46543ed9352c7dfd93071c08b14930cca2e82a08d4reed@android.com 47da94699149a40a90731425766d3b994e34c5ba26deanm@chromium.orgstatic inline int clamp_signed_byte(int n) { 48a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com if (n < 0) { 49a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com n = 0; 50a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com } else if (n > 255) { 51a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com n = 255; 52a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com } 53a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com return n; 54a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com} 55a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com 56da94699149a40a90731425766d3b994e34c5ba26deanm@chromium.orgstatic inline int clamp_div255round(int prod) { 57a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com if (prod <= 0) { 58a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com return 0; 59a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com } else if (prod >= 255*255) { 60a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com return 255; 61a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com } else { 62a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com return SkDiv255Round(prod); 63a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com } 64a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com} 65a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org// kClear_Mode, //!< [0, 0] 6948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic SkPMColor clear_modeproc(SkPMColor src, SkPMColor dst) { 7048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return 0; 718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org// kSrc_Mode, //!< [Sa, Sc] 7448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic SkPMColor src_modeproc(SkPMColor src, SkPMColor dst) { 7548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return src; 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org// kDst_Mode, //!< [Da, Dc] 7948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic SkPMColor dst_modeproc(SkPMColor src, SkPMColor dst) { 8048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return dst; 8148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 831447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com// kSrcOver_Mode, //!< [Sa + Da - Sa*Da, Sc + (1 - Sa)*Dc] 8448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic SkPMColor srcover_modeproc(SkPMColor src, SkPMColor dst) { 8548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org#if 0 8648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org // this is the old, more-correct way, but it doesn't guarantee that dst==255 8748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org // will always stay opaque 8848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return src + SkAlphaMulQ(dst, SkAlpha255To256(255 - SkGetPackedA32(src))); 8948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org#else 9048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org // this is slightly faster, but more importantly guarantees that dst==255 9148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org // will always stay opaque 9248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return src + SkAlphaMulQ(dst, 256 - SkGetPackedA32(src)); 9348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org#endif 948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org// kDstOver_Mode, //!< [Sa + Da - Sa*Da, Dc + (1 - Da)*Sc] 9748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic SkPMColor dstover_modeproc(SkPMColor src, SkPMColor dst) { 9848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org // this is the reverse of srcover, just flipping src and dst 9948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org // see srcover's comment about the 256 for opaqueness guarantees 10048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return dst + SkAlphaMulQ(src, 256 - SkGetPackedA32(dst)); 10148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org// kSrcIn_Mode, //!< [Sa * Da, Sc * Da] 10448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic SkPMColor srcin_modeproc(SkPMColor src, SkPMColor dst) { 10548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return SkAlphaMulQ(src, SkAlpha255To256(SkGetPackedA32(dst))); 1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org// kDstIn_Mode, //!< [Sa * Da, Sa * Dc] 10948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic SkPMColor dstin_modeproc(SkPMColor src, SkPMColor dst) { 11048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return SkAlphaMulQ(dst, SkAlpha255To256(SkGetPackedA32(src))); 1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org// kSrcOut_Mode, //!< [Sa * (1 - Da), Sc * (1 - Da)] 11448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic SkPMColor srcout_modeproc(SkPMColor src, SkPMColor dst) { 11548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return SkAlphaMulQ(src, SkAlpha255To256(255 - SkGetPackedA32(dst))); 11648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org// kDstOut_Mode, //!< [Da * (1 - Sa), Dc * (1 - Sa)] 11948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic SkPMColor dstout_modeproc(SkPMColor src, SkPMColor dst) { 12048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return SkAlphaMulQ(dst, SkAlpha255To256(255 - SkGetPackedA32(src))); 1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org// kSrcATop_Mode, //!< [Da, Sc * Da + (1 - Sa) * Dc] 12448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic SkPMColor srcatop_modeproc(SkPMColor src, SkPMColor dst) { 12548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org unsigned sa = SkGetPackedA32(src); 12648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org unsigned da = SkGetPackedA32(dst); 12748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org unsigned isa = 255 - sa; 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return SkPackARGB32(da, 13048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkAlphaMulAlpha(da, SkGetPackedR32(src)) + 13148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkAlphaMulAlpha(isa, SkGetPackedR32(dst)), 13248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkAlphaMulAlpha(da, SkGetPackedG32(src)) + 13348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkAlphaMulAlpha(isa, SkGetPackedG32(dst)), 13448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkAlphaMulAlpha(da, SkGetPackedB32(src)) + 13548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkAlphaMulAlpha(isa, SkGetPackedB32(dst))); 13648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org// kDstATop_Mode, //!< [Sa, Sa * Dc + Sc * (1 - Da)] 13948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic SkPMColor dstatop_modeproc(SkPMColor src, SkPMColor dst) { 14048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org unsigned sa = SkGetPackedA32(src); 14148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org unsigned da = SkGetPackedA32(dst); 14248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org unsigned ida = 255 - da; 1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return SkPackARGB32(sa, 14548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkAlphaMulAlpha(ida, SkGetPackedR32(src)) + 14648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkAlphaMulAlpha(sa, SkGetPackedR32(dst)), 14748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkAlphaMulAlpha(ida, SkGetPackedG32(src)) + 14848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkAlphaMulAlpha(sa, SkGetPackedG32(dst)), 14948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkAlphaMulAlpha(ida, SkGetPackedB32(src)) + 15048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkAlphaMulAlpha(sa, SkGetPackedB32(dst))); 1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 15348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org// kXor_Mode [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc] 15448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic SkPMColor xor_modeproc(SkPMColor src, SkPMColor dst) { 15548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org unsigned sa = SkGetPackedA32(src); 15648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org unsigned da = SkGetPackedA32(dst); 15748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org unsigned isa = 255 - sa; 15848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org unsigned ida = 255 - da; 1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return SkPackARGB32(sa + da - (SkAlphaMulAlpha(sa, da) << 1), 16148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkAlphaMulAlpha(ida, SkGetPackedR32(src)) + 16248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkAlphaMulAlpha(isa, SkGetPackedR32(dst)), 16348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkAlphaMulAlpha(ida, SkGetPackedG32(src)) + 16448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkAlphaMulAlpha(isa, SkGetPackedG32(dst)), 16548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkAlphaMulAlpha(ida, SkGetPackedB32(src)) + 16648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkAlphaMulAlpha(isa, SkGetPackedB32(dst))); 16748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org/////////////////////////////////////////////////////////////////////////////// 17048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 17148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org// kPlus_Mode 17248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic SkPMColor plus_modeproc(SkPMColor src, SkPMColor dst) { 17348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org unsigned b = saturated_add(SkGetPackedB32(src), SkGetPackedB32(dst)); 17448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org unsigned g = saturated_add(SkGetPackedG32(src), SkGetPackedG32(dst)); 17548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org unsigned r = saturated_add(SkGetPackedR32(src), SkGetPackedR32(dst)); 17648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org unsigned a = saturated_add(SkGetPackedA32(src), SkGetPackedA32(dst)); 17748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return SkPackARGB32(a, r, g, b); 1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1808d3cd7a170c810e3816bf00220cbef51e7b16795reed@google.com// kModulate_Mode 1818d3cd7a170c810e3816bf00220cbef51e7b16795reed@google.comstatic SkPMColor modulate_modeproc(SkPMColor src, SkPMColor dst) { 18248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int a = SkAlphaMulAlpha(SkGetPackedA32(src), SkGetPackedA32(dst)); 18348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int r = SkAlphaMulAlpha(SkGetPackedR32(src), SkGetPackedR32(dst)); 18448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int g = SkAlphaMulAlpha(SkGetPackedG32(src), SkGetPackedG32(dst)); 18548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int b = SkAlphaMulAlpha(SkGetPackedB32(src), SkGetPackedB32(dst)); 18648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return SkPackARGB32(a, r, g, b); 18748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 189a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.comstatic inline int srcover_byte(int a, int b) { 190a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com return a + b - SkAlphaMulAlpha(a, b); 191a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com} 19225cfa693420b6da4182bda42ba15970999b840ddreed@google.com 19325cfa693420b6da4182bda42ba15970999b840ddreed@google.com// kMultiply_Mode 19425cfa693420b6da4182bda42ba15970999b840ddreed@google.com// B(Cb, Cs) = Cb x Cs 19525cfa693420b6da4182bda42ba15970999b840ddreed@google.com// multiply uses its own version of blendfunc_byte because sa and da are not needed 19625cfa693420b6da4182bda42ba15970999b840ddreed@google.comstatic int blendfunc_multiply_byte(int sc, int dc, int sa, int da) { 19725cfa693420b6da4182bda42ba15970999b840ddreed@google.com return clamp_div255round(sc * (255 - da) + dc * (255 - sa) + sc * dc); 19825cfa693420b6da4182bda42ba15970999b840ddreed@google.com} 19925cfa693420b6da4182bda42ba15970999b840ddreed@google.com 20025cfa693420b6da4182bda42ba15970999b840ddreed@google.comstatic SkPMColor multiply_modeproc(SkPMColor src, SkPMColor dst) { 20125cfa693420b6da4182bda42ba15970999b840ddreed@google.com int sa = SkGetPackedA32(src); 20225cfa693420b6da4182bda42ba15970999b840ddreed@google.com int da = SkGetPackedA32(dst); 20325cfa693420b6da4182bda42ba15970999b840ddreed@google.com int a = srcover_byte(sa, da); 20425cfa693420b6da4182bda42ba15970999b840ddreed@google.com int r = blendfunc_multiply_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 20525cfa693420b6da4182bda42ba15970999b840ddreed@google.com int g = blendfunc_multiply_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 20625cfa693420b6da4182bda42ba15970999b840ddreed@google.com int b = blendfunc_multiply_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 20725cfa693420b6da4182bda42ba15970999b840ddreed@google.com return SkPackARGB32(a, r, g, b); 20825cfa693420b6da4182bda42ba15970999b840ddreed@google.com} 20925cfa693420b6da4182bda42ba15970999b840ddreed@google.com 21025cfa693420b6da4182bda42ba15970999b840ddreed@google.com// kScreen_Mode 211a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.comstatic SkPMColor screen_modeproc(SkPMColor src, SkPMColor dst) { 212a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int a = srcover_byte(SkGetPackedA32(src), SkGetPackedA32(dst)); 213a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int r = srcover_byte(SkGetPackedR32(src), SkGetPackedR32(dst)); 214a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int g = srcover_byte(SkGetPackedG32(src), SkGetPackedG32(dst)); 215a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int b = srcover_byte(SkGetPackedB32(src), SkGetPackedB32(dst)); 216a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com return SkPackARGB32(a, r, g, b); 217a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com} 218a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com 219a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com// kOverlay_Mode 220a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.comstatic inline int overlay_byte(int sc, int dc, int sa, int da) { 221a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int tmp = sc * (255 - da) + dc * (255 - sa); 222a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int rc; 223a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com if (2 * dc <= da) { 224a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com rc = 2 * sc * dc; 225a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com } else { 226a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com rc = sa * da - 2 * (da - dc) * (sa - sc); 227a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com } 228a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com return clamp_div255round(rc + tmp); 229a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com} 230a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.comstatic SkPMColor overlay_modeproc(SkPMColor src, SkPMColor dst) { 231a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int sa = SkGetPackedA32(src); 232a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int da = SkGetPackedA32(dst); 233a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int a = srcover_byte(sa, da); 234a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int r = overlay_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 235a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int g = overlay_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 236a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int b = overlay_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 237a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com return SkPackARGB32(a, r, g, b); 238a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com} 239a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com 240a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com// kDarken_Mode 241a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.comstatic inline int darken_byte(int sc, int dc, int sa, int da) { 242a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int sd = sc * da; 243a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int ds = dc * sa; 244a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com if (sd < ds) { 245a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com // srcover 246a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com return sc + dc - SkDiv255Round(ds); 247a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com } else { 248a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com // dstover 249a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com return dc + sc - SkDiv255Round(sd); 250a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com } 251a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com} 2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkPMColor darken_modeproc(SkPMColor src, SkPMColor dst) { 253a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int sa = SkGetPackedA32(src); 254a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int da = SkGetPackedA32(dst); 255a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int a = srcover_byte(sa, da); 256a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int r = darken_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 257a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int g = darken_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 258a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int b = darken_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 259a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com return SkPackARGB32(a, r, g, b); 260a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com} 2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 262a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com// kLighten_Mode 263a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.comstatic inline int lighten_byte(int sc, int dc, int sa, int da) { 264a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int sd = sc * da; 265a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int ds = dc * sa; 266a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com if (sd > ds) { 267a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com // srcover 268a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com return sc + dc - SkDiv255Round(ds); 269a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com } else { 270a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com // dstover 271a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com return dc + sc - SkDiv255Round(sd); 272a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com } 273a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com} 274a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.comstatic SkPMColor lighten_modeproc(SkPMColor src, SkPMColor dst) { 275a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int sa = SkGetPackedA32(src); 276a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int da = SkGetPackedA32(dst); 277a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int a = srcover_byte(sa, da); 278a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int r = lighten_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 279a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int g = lighten_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 280a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int b = lighten_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 281a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com return SkPackARGB32(a, r, g, b); 282a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com} 2838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 284a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com// kColorDodge_Mode 285a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.comstatic inline int colordodge_byte(int sc, int dc, int sa, int da) { 286a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int diff = sa - sc; 287a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int rc; 288311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org if (0 == dc) { 289311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org return SkAlphaMulAlpha(sc, 255 - da); 290311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org } else if (0 == diff) { 291a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com rc = sa * da + sc * (255 - da) + dc * (255 - sa); 292a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com } else { 293311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org diff = dc * sa / diff; 294311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org rc = sa * ((da < diff) ? da : diff) + sc * (255 - da) + dc * (255 - sa); 295a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com } 296311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org return clamp_div255round(rc); 29748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 29848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic SkPMColor colordodge_modeproc(SkPMColor src, SkPMColor dst) { 29948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int sa = SkGetPackedA32(src); 30048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int da = SkGetPackedA32(dst); 30148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int a = srcover_byte(sa, da); 30248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int r = colordodge_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 30348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int g = colordodge_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 30448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int b = colordodge_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 30548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return SkPackARGB32(a, r, g, b); 30648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 30748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 30848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org// kColorBurn_Mode 30948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic inline int colorburn_byte(int sc, int dc, int sa, int da) { 31048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int rc; 311311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org if (dc == da) { 312311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org rc = sa * da + sc * (255 - da) + dc * (255 - sa); 31348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } else if (0 == sc) { 31448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return SkAlphaMulAlpha(dc, 255 - sa); 31548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } else { 316311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org int tmp = (da - dc) * sa / sc; 317311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org rc = sa * (da - ((da < tmp) ? da : tmp)) 318311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org + sc * (255 - da) + dc * (255 - sa); 31948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } 320311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org return clamp_div255round(rc); 32148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 32248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic SkPMColor colorburn_modeproc(SkPMColor src, SkPMColor dst) { 32348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int sa = SkGetPackedA32(src); 32448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int da = SkGetPackedA32(dst); 32548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int a = srcover_byte(sa, da); 32648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int r = colorburn_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 32748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int g = colorburn_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 32848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int b = colorburn_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 32948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return SkPackARGB32(a, r, g, b); 33048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 33148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 33248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org// kHardLight_Mode 33348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic inline int hardlight_byte(int sc, int dc, int sa, int da) { 33448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int rc; 33548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org if (2 * sc <= sa) { 33648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org rc = 2 * sc * dc; 33748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } else { 33848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org rc = sa * da - 2 * (da - dc) * (sa - sc); 33948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } 34048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return clamp_div255round(rc + sc * (255 - da) + dc * (255 - sa)); 34148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 34248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic SkPMColor hardlight_modeproc(SkPMColor src, SkPMColor dst) { 34348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int sa = SkGetPackedA32(src); 34448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int da = SkGetPackedA32(dst); 34548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int a = srcover_byte(sa, da); 34648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int r = hardlight_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 34748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int g = hardlight_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 34848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int b = hardlight_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 34948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return SkPackARGB32(a, r, g, b); 35048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 35148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 35248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org// returns 255 * sqrt(n/255) 35348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic U8CPU sqrt_unit_byte(U8CPU n) { 35448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return SkSqrtBits(n, 15+4); 35548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 35648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 35748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org// kSoftLight_Mode 35848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic inline int softlight_byte(int sc, int dc, int sa, int da) { 35948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int m = da ? dc * 256 / da : 0; 36048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int rc; 36148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org if (2 * sc <= sa) { 36248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org rc = dc * (sa + ((2 * sc - sa) * (256 - m) >> 8)); 36348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } else if (4 * dc <= da) { 36448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int tmp = (4 * m * (4 * m + 256) * (m - 256) >> 16) + 7 * m; 36548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org rc = dc * sa + (da * (2 * sc - sa) * tmp >> 8); 36648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } else { 36748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int tmp = sqrt_unit_byte(m) - m; 36848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org rc = dc * sa + (da * (2 * sc - sa) * tmp >> 8); 36948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } 37048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return clamp_div255round(rc + sc * (255 - da) + dc * (255 - sa)); 37148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 37248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic SkPMColor softlight_modeproc(SkPMColor src, SkPMColor dst) { 37348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int sa = SkGetPackedA32(src); 37448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int da = SkGetPackedA32(dst); 37548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int a = srcover_byte(sa, da); 37648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int r = softlight_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 37748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int g = softlight_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 37848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int b = softlight_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 37948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return SkPackARGB32(a, r, g, b); 38048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 38148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 38248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org// kDifference_Mode 38348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic inline int difference_byte(int sc, int dc, int sa, int da) { 38448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int tmp = SkMin32(sc * da, dc * sa); 38548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return clamp_signed_byte(sc + dc - 2 * SkDiv255Round(tmp)); 38648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 38748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic SkPMColor difference_modeproc(SkPMColor src, SkPMColor dst) { 38848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int sa = SkGetPackedA32(src); 38948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int da = SkGetPackedA32(dst); 39048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int a = srcover_byte(sa, da); 39148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int r = difference_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 39248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int g = difference_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 39348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int b = difference_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 39448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return SkPackARGB32(a, r, g, b); 39548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 39648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 39748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org// kExclusion_Mode 398e38e53b5327e2618a97fb26a697a477b74c44d3dcommit-bot@chromium.orgstatic inline int exclusion_byte(int sc, int dc, int, int) { 39948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org // this equations is wacky, wait for SVG to confirm it 400e38e53b5327e2618a97fb26a697a477b74c44d3dcommit-bot@chromium.org //int r = sc * da + dc * sa - 2 * sc * dc + sc * (255 - da) + dc * (255 - sa); 401e38e53b5327e2618a97fb26a697a477b74c44d3dcommit-bot@chromium.org 402e38e53b5327e2618a97fb26a697a477b74c44d3dcommit-bot@chromium.org // The above equation can be simplified as follows 403e38e53b5327e2618a97fb26a697a477b74c44d3dcommit-bot@chromium.org int r = 255*(sc + dc) - 2 * sc * dc; 40448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return clamp_div255round(r); 40548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 40648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic SkPMColor exclusion_modeproc(SkPMColor src, SkPMColor dst) { 40748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int sa = SkGetPackedA32(src); 40848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int da = SkGetPackedA32(dst); 40948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int a = srcover_byte(sa, da); 41048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int r = exclusion_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 41148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int g = exclusion_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 41248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int b = exclusion_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 41348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return SkPackARGB32(a, r, g, b); 41448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 41548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 416b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org// The CSS compositing spec introduces the following formulas: 417b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org// (See https://dvcs.w3.org/hg/FXTF/rawfile/tip/compositing/index.html#blendingnonseparable) 418b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org// SkComputeLuminance is similar to this formula but it uses the new definition from Rec. 709 419b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org// while PDF and CG uses the one from Rec. Rec. 601 420b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org// See http://www.glennchan.info/articles/technical/hd-versus-sd-color-space/hd-versus-sd-color-space.htm 421b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.orgstatic inline int Lum(int r, int g, int b) 422b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org{ 423311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org return SkDiv255Round(r * 77 + g * 150 + b * 28); 424b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org} 425b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 426b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.orgstatic inline int min2(int a, int b) { return a < b ? a : b; } 427b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.orgstatic inline int max2(int a, int b) { return a > b ? a : b; } 42864334352cc3f29f52dfa07225d65eb218d2fd830skia.committer@gmail.com#define minimum(a, b, c) min2(min2(a, b), c) 42964334352cc3f29f52dfa07225d65eb218d2fd830skia.committer@gmail.com#define maximum(a, b, c) max2(max2(a, b), c) 430b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 431b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.orgstatic inline int Sat(int r, int g, int b) { 432b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org return maximum(r, g, b) - minimum(r, g, b); 433b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org} 434b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 435b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.orgstatic inline void setSaturationComponents(int* Cmin, int* Cmid, int* Cmax, int s) { 4363c1ea3a7e5127513d3b3335d92292e02f273efefreed@google.com if(*Cmax > *Cmin) { 437311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org *Cmid = SkMulDiv(*Cmid - *Cmin, s, *Cmax - *Cmin); 438b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org *Cmax = s; 439b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org } else { 440b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org *Cmax = 0; 441b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org *Cmid = 0; 442b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org } 443b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 444b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org *Cmin = 0; 445b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org} 446b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 447b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.orgstatic inline void SetSat(int* r, int* g, int* b, int s) { 448b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org if(*r <= *g) { 449b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org if(*g <= *b) { 450b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org setSaturationComponents(r, g, b, s); 451b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org } else if(*r <= *b) { 452b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org setSaturationComponents(r, b, g, s); 453b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org } else { 454b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org setSaturationComponents(b, r, g, s); 455b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org } 456b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org } else if(*r <= *b) { 457b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org setSaturationComponents(g, r, b, s); 458b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org } else if(*g <= *b) { 459b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org setSaturationComponents(g, b, r, s); 460b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org } else { 461b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org setSaturationComponents(b, g, r, s); 462b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org } 463b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org} 464b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 465311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.orgstatic inline void clipColor(int* r, int* g, int* b, int a) { 466b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int L = Lum(*r, *g, *b); 467b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int n = minimum(*r, *g, *b); 468b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int x = maximum(*r, *g, *b); 469b85ebea5267ec0b9630d828840fa2d7df29b9f43commit-bot@chromium.org int denom; 470b85ebea5267ec0b9630d828840fa2d7df29b9f43commit-bot@chromium.org if ((n < 0) && (denom = L - n)) { // Compute denom and make sure it's non zero 471b85ebea5267ec0b9630d828840fa2d7df29b9f43commit-bot@chromium.org *r = L + SkMulDiv(*r - L, L, denom); 472b85ebea5267ec0b9630d828840fa2d7df29b9f43commit-bot@chromium.org *g = L + SkMulDiv(*g - L, L, denom); 473b85ebea5267ec0b9630d828840fa2d7df29b9f43commit-bot@chromium.org *b = L + SkMulDiv(*b - L, L, denom); 474b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org } 475b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 476b85ebea5267ec0b9630d828840fa2d7df29b9f43commit-bot@chromium.org if ((x > a) && (denom = x - L)) { // Compute denom and make sure it's non zero 477b85ebea5267ec0b9630d828840fa2d7df29b9f43commit-bot@chromium.org int numer = a - L; 478b85ebea5267ec0b9630d828840fa2d7df29b9f43commit-bot@chromium.org *r = L + SkMulDiv(*r - L, numer, denom); 479b85ebea5267ec0b9630d828840fa2d7df29b9f43commit-bot@chromium.org *g = L + SkMulDiv(*g - L, numer, denom); 480b85ebea5267ec0b9630d828840fa2d7df29b9f43commit-bot@chromium.org *b = L + SkMulDiv(*b - L, numer, denom); 481b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org } 482b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org} 483b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 484311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.orgstatic inline void SetLum(int* r, int* g, int* b, int a, int l) { 485b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int d = l - Lum(*r, *g, *b); 486b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org *r += d; 487b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org *g += d; 488b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org *b += d; 489b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 490311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org clipColor(r, g, b, a); 491b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org} 492b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 493b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org// non-separable blend modes are done in non-premultiplied alpha 494b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org#define blendfunc_nonsep_byte(sc, dc, sa, da, blendval) \ 495311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org clamp_div255round(sc * (255 - da) + dc * (255 - sa) + blendval) 496b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 497b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org// kHue_Mode 498b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org// B(Cb, Cs) = SetLum(SetSat(Cs, Sat(Cb)), Lum(Cb)) 499b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org// Create a color with the hue of the source color and the saturation and luminosity of the backdrop color. 500b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.orgstatic SkPMColor hue_modeproc(SkPMColor src, SkPMColor dst) { 501b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int sr = SkGetPackedR32(src); 502b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int sg = SkGetPackedG32(src); 503b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int sb = SkGetPackedB32(src); 504b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int sa = SkGetPackedA32(src); 505b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 506b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int dr = SkGetPackedR32(dst); 507b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int dg = SkGetPackedG32(dst); 508b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int db = SkGetPackedB32(dst); 509b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int da = SkGetPackedA32(dst); 510b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int Sr, Sg, Sb; 511b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 512b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org if(sa && da) { 513311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org Sr = sr * sa; 514311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org Sg = sg * sa; 515311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org Sb = sb * sa; 516311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org SetSat(&Sr, &Sg, &Sb, Sat(dr, dg, db) * sa); 517311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org SetLum(&Sr, &Sg, &Sb, sa * da, Lum(dr, dg, db) * sa); 518b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org } else { 519b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org Sr = 0; 520b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org Sg = 0; 521b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org Sb = 0; 522b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org } 523b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 524b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int a = srcover_byte(sa, da); 525b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int r = blendfunc_nonsep_byte(sr, dr, sa, da, Sr); 526b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int g = blendfunc_nonsep_byte(sg, dg, sa, da, Sg); 527b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int b = blendfunc_nonsep_byte(sb, db, sa, da, Sb); 528b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org return SkPackARGB32(a, r, g, b); 529b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org} 530b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 531b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org// kSaturation_Mode 532b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org// B(Cb, Cs) = SetLum(SetSat(Cb, Sat(Cs)), Lum(Cb)) 53364334352cc3f29f52dfa07225d65eb218d2fd830skia.committer@gmail.com// Create a color with the saturation of the source color and the hue and luminosity of the backdrop color. 534b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.orgstatic SkPMColor saturation_modeproc(SkPMColor src, SkPMColor dst) { 535b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int sr = SkGetPackedR32(src); 536b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int sg = SkGetPackedG32(src); 537b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int sb = SkGetPackedB32(src); 538b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int sa = SkGetPackedA32(src); 539b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 540b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int dr = SkGetPackedR32(dst); 541b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int dg = SkGetPackedG32(dst); 542b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int db = SkGetPackedB32(dst); 543b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int da = SkGetPackedA32(dst); 544b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int Dr, Dg, Db; 545b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 546b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org if(sa && da) { 547311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org Dr = dr * sa; 548311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org Dg = dg * sa; 549311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org Db = db * sa; 550311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org SetSat(&Dr, &Dg, &Db, Sat(sr, sg, sb) * da); 551311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org SetLum(&Dr, &Dg, &Db, sa * da, Lum(dr, dg, db) * sa); 552b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org } else { 553b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org Dr = 0; 554b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org Dg = 0; 555b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org Db = 0; 556b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org } 557b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 558b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int a = srcover_byte(sa, da); 559b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int r = blendfunc_nonsep_byte(sr, dr, sa, da, Dr); 560b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int g = blendfunc_nonsep_byte(sg, dg, sa, da, Dg); 561b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int b = blendfunc_nonsep_byte(sb, db, sa, da, Db); 562b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org return SkPackARGB32(a, r, g, b); 563b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org} 564b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 565b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org// kColor_Mode 566b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org// B(Cb, Cs) = SetLum(Cs, Lum(Cb)) 56764334352cc3f29f52dfa07225d65eb218d2fd830skia.committer@gmail.com// Create a color with the hue and saturation of the source color and the luminosity of the backdrop color. 568b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.orgstatic SkPMColor color_modeproc(SkPMColor src, SkPMColor dst) { 569b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int sr = SkGetPackedR32(src); 570b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int sg = SkGetPackedG32(src); 571b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int sb = SkGetPackedB32(src); 572b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int sa = SkGetPackedA32(src); 573b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 574b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int dr = SkGetPackedR32(dst); 575b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int dg = SkGetPackedG32(dst); 576b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int db = SkGetPackedB32(dst); 577b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int da = SkGetPackedA32(dst); 578b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int Sr, Sg, Sb; 579b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 580b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org if(sa && da) { 581311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org Sr = sr * da; 582311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org Sg = sg * da; 583311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org Sb = sb * da; 584311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org SetLum(&Sr, &Sg, &Sb, sa * da, Lum(dr, dg, db) * sa); 585b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org } else { 586b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org Sr = 0; 587b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org Sg = 0; 588b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org Sb = 0; 589b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org } 590b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 591b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int a = srcover_byte(sa, da); 592b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int r = blendfunc_nonsep_byte(sr, dr, sa, da, Sr); 593b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int g = blendfunc_nonsep_byte(sg, dg, sa, da, Sg); 594b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int b = blendfunc_nonsep_byte(sb, db, sa, da, Sb); 595b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org return SkPackARGB32(a, r, g, b); 596b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org} 597b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 598b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org// kLuminosity_Mode 599b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org// B(Cb, Cs) = SetLum(Cb, Lum(Cs)) 60064334352cc3f29f52dfa07225d65eb218d2fd830skia.committer@gmail.com// Create a color with the luminosity of the source color and the hue and saturation of the backdrop color. 601b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.orgstatic SkPMColor luminosity_modeproc(SkPMColor src, SkPMColor dst) { 602b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int sr = SkGetPackedR32(src); 603b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int sg = SkGetPackedG32(src); 604b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int sb = SkGetPackedB32(src); 605b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int sa = SkGetPackedA32(src); 606b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 607b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int dr = SkGetPackedR32(dst); 608b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int dg = SkGetPackedG32(dst); 609b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int db = SkGetPackedB32(dst); 610b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int da = SkGetPackedA32(dst); 611b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int Dr, Dg, Db; 612b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 613b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org if(sa && da) { 614311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org Dr = dr * sa; 615311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org Dg = dg * sa; 616311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org Db = db * sa; 617311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org SetLum(&Dr, &Dg, &Db, sa * da, Lum(sr, sg, sb) * da); 618b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org } else { 619b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org Dr = 0; 620b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org Dg = 0; 621b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org Db = 0; 622b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org } 623b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 624b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int a = srcover_byte(sa, da); 625b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int r = blendfunc_nonsep_byte(sr, dr, sa, da, Dr); 626b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int g = blendfunc_nonsep_byte(sg, dg, sa, da, Dg); 627b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int b = blendfunc_nonsep_byte(sb, db, sa, da, Db); 628b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org return SkPackARGB32(a, r, g, b); 629b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org} 630b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 631df187c7eb27d7616b75d91f3329deb97c4cd6de2commit-bot@chromium.orgconst ProcCoeff gProcCoeffs[] = { 63248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org { clear_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kZero_Coeff }, 63348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org { src_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kZero_Coeff }, 63448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org { dst_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kOne_Coeff }, 63548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org { srcover_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kISA_Coeff }, 63648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org { dstover_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kOne_Coeff }, 63748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org { srcin_modeproc, SkXfermode::kDA_Coeff, SkXfermode::kZero_Coeff }, 63848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org { dstin_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kSA_Coeff }, 63948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org { srcout_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kZero_Coeff }, 64048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org { dstout_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kISA_Coeff }, 64148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org { srcatop_modeproc, SkXfermode::kDA_Coeff, SkXfermode::kISA_Coeff }, 64248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org { dstatop_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kSA_Coeff }, 64348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org { xor_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kISA_Coeff }, 64448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 645521e34e2912d835ab1b33a06cb8fb416510d7c53reed@google.com { plus_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kOne_Coeff }, 6468d3cd7a170c810e3816bf00220cbef51e7b16795reed@google.com { modulate_modeproc,SkXfermode::kZero_Coeff, SkXfermode::kSC_Coeff }, 647b0091b8382970c28dba57adc170e27b2e3d7394absalomon@google.com { screen_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kISC_Coeff }, 64848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org { overlay_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 64948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org { darken_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 65048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org { lighten_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 65148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org { colordodge_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 65248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org { colorburn_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 65348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org { hardlight_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 65448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org { softlight_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 65548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org { difference_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 65648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org { exclusion_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 65725cfa693420b6da4182bda42ba15970999b840ddreed@google.com { multiply_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 658b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org { hue_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 659b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org { saturation_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 660b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org { color_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 661b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org { luminosity_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 66248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org}; 66348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 66448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org/////////////////////////////////////////////////////////////////////////////// 66548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 66630da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.combool SkXfermode::asMode(Mode* mode) const { 667c0d4aa2088a0788f9df221497945d2ba1b342f44reed@google.com return false; 66848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 66948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 670b0a8a377f832c59cee939ad721e1f87d378b7142joshualittbool SkXfermode::asFragmentProcessor(GrFragmentProcessor**, GrTexture*) const { 6711a6382f5e76c051ffbbb60f3a68524dfe57cf798senorblanco@chromium.org return false; 672f51c01328dc52a87c07e056d6fc4eb7452ccac7absalomon@google.com} 673f51c01328dc52a87c07e056d6fc4eb7452ccac7absalomon@google.com 674378092f3d10b1dd62967f419c35cfefec7c10ee7egdanielbool SkXfermode::asXPFactory(GrXPFactory**) const { 675378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel return false; 676378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel} 677378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel 678378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel 679378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel#if SK_SUPPORT_GPU 680378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel#include "effects/GrPorterDuffXferProcessor.h" 681378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel 68258136167fc596fb945b58b34f500cf370c0dec7cegdanielbool SkXfermode::AsXPFactory(SkXfermode* xfermode, GrXPFactory** xpf) { 683f51c01328dc52a87c07e056d6fc4eb7452ccac7absalomon@google.com if (NULL == xfermode) { 68458136167fc596fb945b58b34f500cf370c0dec7cegdaniel if (xpf) { 68558136167fc596fb945b58b34f500cf370c0dec7cegdaniel *xpf = GrPorterDuffXPFactory::Create(kSrcOver_Mode); 68658136167fc596fb945b58b34f500cf370c0dec7cegdaniel } 6871a6382f5e76c051ffbbb60f3a68524dfe57cf798senorblanco@chromium.org return true; 688f51c01328dc52a87c07e056d6fc4eb7452ccac7absalomon@google.com } else { 68958136167fc596fb945b58b34f500cf370c0dec7cegdaniel return xfermode->asXPFactory(xpf); 690f51c01328dc52a87c07e056d6fc4eb7452ccac7absalomon@google.com } 691f51c01328dc52a87c07e056d6fc4eb7452ccac7absalomon@google.com} 692378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel#else 69358136167fc596fb945b58b34f500cf370c0dec7cegdanielbool SkXfermode::AsXPFactory(SkXfermode* xfermode, GrXPFactory** xpf) { 694378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel return false; 695378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel} 696378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel#endif 697f51c01328dc52a87c07e056d6fc4eb7452ccac7absalomon@google.com 69830da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.comSkPMColor SkXfermode::xferColor(SkPMColor src, SkPMColor dst) const{ 69948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org // no-op. subclasses should override this 70048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return dst; 70148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 70248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 703a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.comvoid SkXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 704a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com const SkPMColor* SK_RESTRICT src, int count, 70530da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.com const SkAlpha* SK_RESTRICT aa) const { 70648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkASSERT(dst && src && count >= 0); 70748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 70848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org if (NULL == aa) { 70948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org for (int i = count - 1; i >= 0; --i) { 71048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org dst[i] = this->xferColor(src[i], dst[i]); 71148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } 71248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } else { 71348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org for (int i = count - 1; i >= 0; --i) { 71448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org unsigned a = aa[i]; 71548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org if (0 != a) { 71648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkPMColor dstC = dst[i]; 71748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkPMColor C = this->xferColor(src[i], dstC); 71848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org if (0xFF != a) { 71948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org C = SkFourByteInterp(C, dstC, a); 72048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } 72148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org dst[i] = C; 72248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } 72348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } 72448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } 72548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 72648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 727a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.comvoid SkXfermode::xfer16(uint16_t* dst, 728a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com const SkPMColor* SK_RESTRICT src, int count, 72930da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.com const SkAlpha* SK_RESTRICT aa) const { 73048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkASSERT(dst && src && count >= 0); 73148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 73248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org if (NULL == aa) { 73348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org for (int i = count - 1; i >= 0; --i) { 73448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkPMColor dstC = SkPixel16ToPixel32(dst[i]); 73548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org dst[i] = SkPixel32ToPixel16_ToU16(this->xferColor(src[i], dstC)); 73648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } 73748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } else { 73848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org for (int i = count - 1; i >= 0; --i) { 73948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org unsigned a = aa[i]; 74048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org if (0 != a) { 74148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkPMColor dstC = SkPixel16ToPixel32(dst[i]); 74248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkPMColor C = this->xferColor(src[i], dstC); 74348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org if (0xFF != a) { 74448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org C = SkFourByteInterp(C, dstC, a); 74548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } 74648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org dst[i] = SkPixel32ToPixel16_ToU16(C); 74748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } 74848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } 74948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } 75048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 75148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 752a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.comvoid SkXfermode::xferA8(SkAlpha* SK_RESTRICT dst, 75348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org const SkPMColor src[], int count, 75430da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.com const SkAlpha* SK_RESTRICT aa) const { 75548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkASSERT(dst && src && count >= 0); 75648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 75748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org if (NULL == aa) { 75848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org for (int i = count - 1; i >= 0; --i) { 75948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkPMColor res = this->xferColor(src[i], (dst[i] << SK_A32_SHIFT)); 76048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org dst[i] = SkToU8(SkGetPackedA32(res)); 76148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } 76248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } else { 76348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org for (int i = count - 1; i >= 0; --i) { 76448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org unsigned a = aa[i]; 76548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org if (0 != a) { 76648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkAlpha dstA = dst[i]; 76748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org unsigned A = SkGetPackedA32(this->xferColor(src[i], 76848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org (SkPMColor)(dstA << SK_A32_SHIFT))); 76948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org if (0xFF != a) { 77048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org A = SkAlphaBlend(A, dstA, SkAlpha255To256(a)); 77148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } 77248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org dst[i] = SkToU8(A); 77348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } 77448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } 77548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } 77648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 77748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 778dcfb7cf336cafffd8d149c908b615e1deaa3a49begdanielbool SkXfermode::supportsCoverageAsAlpha() const { 779dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel return false; 780dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel} 781dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel 782dcfb7cf336cafffd8d149c908b615e1deaa3a49begdanielbool SkXfermode::isOpaque(SkXfermode::SrcColorOpacity opacityType) const { 783dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel return false; 784dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel} 785dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel 78648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org/////////////////////////////////////////////////////////////////////////////// 78748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org/////////////////////////////////////////////////////////////////////////////// 788a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com 7899fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reedSkFlattenable* SkProcCoeffXfermode::CreateProc(SkReadBuffer& buffer) { 7909fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed uint32_t mode32 = buffer.read32(); 7910f7197bc0ddbe6c61732d6fe69df86bdba00a060senorblanco if (!buffer.validate(mode32 < SK_ARRAY_COUNT(gProcCoeffs))) { 7929fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed return NULL; 7939fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed } 7949fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed return SkXfermode::Create((SkXfermode::Mode)mode32); 7959fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed} 7969fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed 7979fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reedvoid SkProcCoeffXfermode::flatten(SkWriteBuffer& buffer) const { 7989fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed buffer.write32(fMode); 7999fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed} 80052314f82ba8696e957e70eabde672b6470fedf7areed@google.com 801df187c7eb27d7616b75d91f3329deb97c4cd6de2commit-bot@chromium.orgbool SkProcCoeffXfermode::asMode(Mode* mode) const { 802df187c7eb27d7616b75d91f3329deb97c4cd6de2commit-bot@chromium.org if (mode) { 803df187c7eb27d7616b75d91f3329deb97c4cd6de2commit-bot@chromium.org *mode = fMode; 80448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } 805df187c7eb27d7616b75d91f3329deb97c4cd6de2commit-bot@chromium.org return true; 806df187c7eb27d7616b75d91f3329deb97c4cd6de2commit-bot@chromium.org} 807c0d4aa2088a0788f9df221497945d2ba1b342f44reed@google.com 808dcfb7cf336cafffd8d149c908b615e1deaa3a49begdanielbool SkProcCoeffXfermode::supportsCoverageAsAlpha() const { 809df187c7eb27d7616b75d91f3329deb97c4cd6de2commit-bot@chromium.org if (CANNOT_USE_COEFF == fSrcCoeff) { 810df187c7eb27d7616b75d91f3329deb97c4cd6de2commit-bot@chromium.org return false; 811c0d4aa2088a0788f9df221497945d2ba1b342f44reed@google.com } 812c0d4aa2088a0788f9df221497945d2ba1b342f44reed@google.com 813dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel switch (fDstCoeff) { 814dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel case SkXfermode::kOne_Coeff: 815dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel case SkXfermode::kISA_Coeff: 816dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel case SkXfermode::kISC_Coeff: 817dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel return true; 818dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel default: 819dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel return false; 820dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel } 821dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel} 822dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel 823dcfb7cf336cafffd8d149c908b615e1deaa3a49begdanielbool SkProcCoeffXfermode::isOpaque(SkXfermode::SrcColorOpacity opacityType) const { 824dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel if (CANNOT_USE_COEFF == fSrcCoeff) { 825dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel return false; 826df187c7eb27d7616b75d91f3329deb97c4cd6de2commit-bot@chromium.org } 8273d626834b4b5ee2d6dda34da365dfe40520253aamtklein 828dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel if (SkXfermode::kDA_Coeff == fSrcCoeff || SkXfermode::kDC_Coeff == fSrcCoeff || 829dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel SkXfermode::kIDA_Coeff == fSrcCoeff || SkXfermode::kIDC_Coeff == fSrcCoeff) { 830dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel return false; 83184cc1ebc5a4789e93e23c65eb4014ef5b8b0bab4commit-bot@chromium.org } 8323d626834b4b5ee2d6dda34da365dfe40520253aamtklein 833dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel switch (fDstCoeff) { 834dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel case SkXfermode::kZero_Coeff: 835dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel return true; 836dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel case SkXfermode::kISA_Coeff: 837dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel return SkXfermode::kOpaque_SrcColorOpacity == opacityType; 838dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel case SkXfermode::kSA_Coeff: 839dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel return SkXfermode::kTransparentBlack_SrcColorOpacity == opacityType || 840dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel SkXfermode::kTransparentAlpha_SrcColorOpacity == opacityType; 841dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel case SkXfermode::kSC_Coeff: 842dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel return SkXfermode::kTransparentBlack_SrcColorOpacity == opacityType; 843dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel default: 844dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel return false; 845dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel } 846dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel 847df187c7eb27d7616b75d91f3329deb97c4cd6de2commit-bot@chromium.org} 8486f980c6a2354fed70a6258fb4dd4155936660930djsollen@google.com 849cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.orgvoid SkProcCoeffXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 850cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org const SkPMColor* SK_RESTRICT src, int count, 851cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org const SkAlpha* SK_RESTRICT aa) const { 852cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org SkASSERT(dst && src && count >= 0); 85360bd7519a9db4ddddd95e490f93165e5676f90f5skia.committer@gmail.com 854cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org SkXfermodeProc proc = fProc; 85560bd7519a9db4ddddd95e490f93165e5676f90f5skia.committer@gmail.com 85649f085dddff10473b6ebf832a974288300224e60bsalomon if (proc) { 857cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org if (NULL == aa) { 858cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org for (int i = count - 1; i >= 0; --i) { 859cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org dst[i] = proc(src[i], dst[i]); 860cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org } 861cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org } else { 862cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org for (int i = count - 1; i >= 0; --i) { 863cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org unsigned a = aa[i]; 864cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org if (0 != a) { 865cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org SkPMColor dstC = dst[i]; 866cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org SkPMColor C = proc(src[i], dstC); 867cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org if (a != 0xFF) { 868cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org C = SkFourByteInterp(C, dstC, a); 869cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org } 870cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org dst[i] = C; 871cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org } 872cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org } 873cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org } 874cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org } 875cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org} 876cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org 877cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.orgvoid SkProcCoeffXfermode::xfer16(uint16_t* SK_RESTRICT dst, 878cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org const SkPMColor* SK_RESTRICT src, int count, 879cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org const SkAlpha* SK_RESTRICT aa) const { 880cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org SkASSERT(dst && src && count >= 0); 88160bd7519a9db4ddddd95e490f93165e5676f90f5skia.committer@gmail.com 882cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org SkXfermodeProc proc = fProc; 88360bd7519a9db4ddddd95e490f93165e5676f90f5skia.committer@gmail.com 88449f085dddff10473b6ebf832a974288300224e60bsalomon if (proc) { 885cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org if (NULL == aa) { 886cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org for (int i = count - 1; i >= 0; --i) { 887cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org SkPMColor dstC = SkPixel16ToPixel32(dst[i]); 888cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org dst[i] = SkPixel32ToPixel16_ToU16(proc(src[i], dstC)); 889cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org } 890cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org } else { 891cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org for (int i = count - 1; i >= 0; --i) { 892cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org unsigned a = aa[i]; 893cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org if (0 != a) { 894cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org SkPMColor dstC = SkPixel16ToPixel32(dst[i]); 895cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org SkPMColor C = proc(src[i], dstC); 896cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org if (0xFF != a) { 897cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org C = SkFourByteInterp(C, dstC, a); 898cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org } 899cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org dst[i] = SkPixel32ToPixel16_ToU16(C); 900cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org } 901cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org } 902cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org } 903cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org } 904cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org} 905cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org 906cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.orgvoid SkProcCoeffXfermode::xferA8(SkAlpha* SK_RESTRICT dst, 907cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org const SkPMColor* SK_RESTRICT src, int count, 908cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org const SkAlpha* SK_RESTRICT aa) const { 909cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org SkASSERT(dst && src && count >= 0); 91060bd7519a9db4ddddd95e490f93165e5676f90f5skia.committer@gmail.com 911cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org SkXfermodeProc proc = fProc; 91260bd7519a9db4ddddd95e490f93165e5676f90f5skia.committer@gmail.com 91349f085dddff10473b6ebf832a974288300224e60bsalomon if (proc) { 914cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org if (NULL == aa) { 915cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org for (int i = count - 1; i >= 0; --i) { 916cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org SkPMColor res = proc(src[i], dst[i] << SK_A32_SHIFT); 917cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org dst[i] = SkToU8(SkGetPackedA32(res)); 918cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org } 919cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org } else { 920cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org for (int i = count - 1; i >= 0; --i) { 921cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org unsigned a = aa[i]; 922cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org if (0 != a) { 923cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org SkAlpha dstA = dst[i]; 924cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org SkPMColor res = proc(src[i], dstA << SK_A32_SHIFT); 925cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org unsigned A = SkGetPackedA32(res); 926cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org if (0xFF != a) { 927cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org A = SkAlphaBlend(A, dstA, SkAlpha255To256(a)); 928cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org } 929cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org dst[i] = SkToU8(A); 930cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org } 931cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org } 932cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org } 933cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org } 934cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org} 935cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org 9366f980c6a2354fed70a6258fb4dd4155936660930djsollen@google.com#if SK_SUPPORT_GPU 9370063a9b69a6a5d377f207c2aa1ea1e7220c19ba9egdaniel#include "effects/GrCustomXfermode.h" 9380063a9b69a6a5d377f207c2aa1ea1e7220c19ba9egdaniel 939b0a8a377f832c59cee939ad721e1f87d378b7142joshualittbool SkProcCoeffXfermode::asFragmentProcessor(GrFragmentProcessor** fp, 940b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrTexture* background) const { 9410063a9b69a6a5d377f207c2aa1ea1e7220c19ba9egdaniel if (GrCustomXfermode::IsSupportedMode(fMode)) { 942b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt if (fp) { 9430063a9b69a6a5d377f207c2aa1ea1e7220c19ba9egdaniel *fp = GrCustomXfermode::CreateFP(fMode, background); 944b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt SkASSERT(*fp); 9456f980c6a2354fed70a6258fb4dd4155936660930djsollen@google.com } 946df187c7eb27d7616b75d91f3329deb97c4cd6de2commit-bot@chromium.org return true; 947f51c01328dc52a87c07e056d6fc4eb7452ccac7absalomon@google.com } 948df187c7eb27d7616b75d91f3329deb97c4cd6de2commit-bot@chromium.org return false; 949df187c7eb27d7616b75d91f3329deb97c4cd6de2commit-bot@chromium.org} 95054f0e9d784122cfd3f5968e0fea971d5b5a4805aegdaniel 95154f0e9d784122cfd3f5968e0fea971d5b5a4805aegdanielbool SkProcCoeffXfermode::asXPFactory(GrXPFactory** xp) const { 95258136167fc596fb945b58b34f500cf370c0dec7cegdaniel if (CANNOT_USE_COEFF != fSrcCoeff) { 95358136167fc596fb945b58b34f500cf370c0dec7cegdaniel if (xp) { 95458136167fc596fb945b58b34f500cf370c0dec7cegdaniel *xp = GrPorterDuffXPFactory::Create(fMode); 95558136167fc596fb945b58b34f500cf370c0dec7cegdaniel SkASSERT(*xp); 95658136167fc596fb945b58b34f500cf370c0dec7cegdaniel } 95758136167fc596fb945b58b34f500cf370c0dec7cegdaniel return true; 95858136167fc596fb945b58b34f500cf370c0dec7cegdaniel } 95958136167fc596fb945b58b34f500cf370c0dec7cegdaniel 96054f0e9d784122cfd3f5968e0fea971d5b5a4805aegdaniel if (GrCustomXfermode::IsSupportedMode(fMode)) { 96154f0e9d784122cfd3f5968e0fea971d5b5a4805aegdaniel if (xp) { 96254f0e9d784122cfd3f5968e0fea971d5b5a4805aegdaniel *xp = GrCustomXfermode::CreateXPFactory(fMode); 96354f0e9d784122cfd3f5968e0fea971d5b5a4805aegdaniel SkASSERT(*xp); 96454f0e9d784122cfd3f5968e0fea971d5b5a4805aegdaniel } 96554f0e9d784122cfd3f5968e0fea971d5b5a4805aegdaniel return true; 96654f0e9d784122cfd3f5968e0fea971d5b5a4805aegdaniel } 96754f0e9d784122cfd3f5968e0fea971d5b5a4805aegdaniel return false; 96854f0e9d784122cfd3f5968e0fea971d5b5a4805aegdaniel} 96926e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com#endif 970f51c01328dc52a87c07e056d6fc4eb7452ccac7absalomon@google.com 971d7aaf6034e519ea9b70649c1d344f2f24de90ccbcommit-bot@chromium.orgconst char* SkXfermode::ModeName(Mode mode) { 972d7aaf6034e519ea9b70649c1d344f2f24de90ccbcommit-bot@chromium.org SkASSERT((unsigned) mode <= (unsigned)kLastMode); 973d7aaf6034e519ea9b70649c1d344f2f24de90ccbcommit-bot@chromium.org const char* gModeStrings[] = { 974b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com "Clear", "Src", "Dst", "SrcOver", "DstOver", "SrcIn", "DstIn", 975b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com "SrcOut", "DstOut", "SrcATop", "DstATop", "Xor", "Plus", 9768d3cd7a170c810e3816bf00220cbef51e7b16795reed@google.com "Modulate", "Screen", "Overlay", "Darken", "Lighten", "ColorDodge", 977d7aaf6034e519ea9b70649c1d344f2f24de90ccbcommit-bot@chromium.org "ColorBurn", "HardLight", "SoftLight", "Difference", "Exclusion", 978d7aaf6034e519ea9b70649c1d344f2f24de90ccbcommit-bot@chromium.org "Multiply", "Hue", "Saturation", "Color", "Luminosity" 979b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com }; 980d7aaf6034e519ea9b70649c1d344f2f24de90ccbcommit-bot@chromium.org return gModeStrings[mode]; 981d7aaf6034e519ea9b70649c1d344f2f24de90ccbcommit-bot@chromium.org SK_COMPILE_ASSERT(SK_ARRAY_COUNT(gModeStrings) == kLastMode + 1, mode_count); 982d7aaf6034e519ea9b70649c1d344f2f24de90ccbcommit-bot@chromium.org} 983d7aaf6034e519ea9b70649c1d344f2f24de90ccbcommit-bot@chromium.org 9840f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org#ifndef SK_IGNORE_TO_STRING 985d7aaf6034e519ea9b70649c1d344f2f24de90ccbcommit-bot@chromium.orgvoid SkProcCoeffXfermode::toString(SkString* str) const { 986d7aaf6034e519ea9b70649c1d344f2f24de90ccbcommit-bot@chromium.org str->append("SkProcCoeffXfermode: "); 987b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com 988b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com str->append("mode: "); 989d7aaf6034e519ea9b70649c1d344f2f24de90ccbcommit-bot@chromium.org str->append(ModeName(fMode)); 990b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com 991b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com static const char* gCoeffStrings[kCoeffCount] = { 99298ded84b80918ac1e40224c125922941f3b2eb03skia.committer@gmail.com "Zero", "One", "SC", "ISC", "DC", "IDC", "SA", "ISA", "DA", "IDA" 993b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com }; 994b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com 995b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com str->append(" src: "); 996b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com if (CANNOT_USE_COEFF == fSrcCoeff) { 997b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com str->append("can't use"); 998b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com } else { 999b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com str->append(gCoeffStrings[fSrcCoeff]); 1000b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com } 1001b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com 1002b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com str->append(" dst: "); 1003b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com if (CANNOT_USE_COEFF == fDstCoeff) { 1004b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com str->append("can't use"); 1005b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com } else { 1006b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com str->append(gCoeffStrings[fDstCoeff]); 1007b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com } 1008b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com} 1009b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com#endif 1010b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com 10118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 10128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkClearXfermode : public SkProcCoeffXfermode { 10148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 10150a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org static SkClearXfermode* Create(const ProcCoeff& rec) { 10160a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org return SkNEW_ARGS(SkClearXfermode, (rec)); 10170a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org } 10188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 101936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const override; 102036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void xferA8(SkAlpha*, const SkPMColor*, int, const SkAlpha*) const override; 10218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10220f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org SK_TO_STRING_OVERRIDE() 10231447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 10241447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.comprivate: 10250a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org SkClearXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kClear_Mode) {} 10261447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 1027b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com typedef SkProcCoeffXfermode INHERITED; 10288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 10298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 103086ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.comvoid SkClearXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 103186ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com const SkPMColor* SK_RESTRICT, int count, 103230da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.com const SkAlpha* SK_RESTRICT aa) const { 103386ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com SkASSERT(dst && count >= 0); 10348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 103586ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com if (NULL == aa) { 103686ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com memset(dst, 0, count << 2); 103786ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com } else { 103886ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com for (int i = count - 1; i >= 0; --i) { 103986ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com unsigned a = aa[i]; 104086ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com if (0xFF == a) { 104186ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com dst[i] = 0; 104286ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com } else if (a != 0) { 104386ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com dst[i] = SkAlphaMulQ(dst[i], SkAlpha255To256(255 - a)); 10448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 104786ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com} 104886ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.comvoid SkClearXfermode::xferA8(SkAlpha* SK_RESTRICT dst, 104986ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com const SkPMColor* SK_RESTRICT, int count, 105030da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.com const SkAlpha* SK_RESTRICT aa) const { 105186ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com SkASSERT(dst && count >= 0); 10528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 105386ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com if (NULL == aa) { 105486ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com memset(dst, 0, count); 105586ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com } else { 105686ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com for (int i = count - 1; i >= 0; --i) { 105786ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com unsigned a = aa[i]; 105886ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com if (0xFF == a) { 105986ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com dst[i] = 0; 106086ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com } else if (0 != a) { 106186ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com dst[i] = SkAlphaMulAlpha(dst[i], 255 - a); 10628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 106586ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com} 10661447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 10670f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org#ifndef SK_IGNORE_TO_STRING 1068b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.comvoid SkClearXfermode::toString(SkString* str) const { 1069b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com this->INHERITED::toString(str); 1070b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com} 1071b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com#endif 1072b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com 107386ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com/////////////////////////////////////////////////////////////////////////////// 107486ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com 107586ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.comclass SkSrcXfermode : public SkProcCoeffXfermode { 107686ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.compublic: 10770a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org static SkSrcXfermode* Create(const ProcCoeff& rec) { 10780a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org return SkNEW_ARGS(SkSrcXfermode, (rec)); 10790a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org } 108086ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com 108136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const override; 108236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void xferA8(SkAlpha*, const SkPMColor*, int, const SkAlpha*) const override; 10838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10840f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org SK_TO_STRING_OVERRIDE() 10851447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 10861447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.comprivate: 10870a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org SkSrcXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kSrc_Mode) {} 1088b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com typedef SkProcCoeffXfermode INHERITED; 10898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 10908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 109186ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.comvoid SkSrcXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 109286ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com const SkPMColor* SK_RESTRICT src, int count, 109330da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.com const SkAlpha* SK_RESTRICT aa) const { 109486ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com SkASSERT(dst && src && count >= 0); 10951447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 109686ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com if (NULL == aa) { 109786ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com memcpy(dst, src, count << 2); 109886ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com } else { 109986ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com for (int i = count - 1; i >= 0; --i) { 110086ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com unsigned a = aa[i]; 110186ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com if (a == 0xFF) { 110286ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com dst[i] = src[i]; 110386ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com } else if (a != 0) { 110486ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com dst[i] = SkFourByteInterp(src[i], dst[i], a); 110586ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com } 110686ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com } 110786ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com } 110886ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com} 110986ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com 111086ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.comvoid SkSrcXfermode::xferA8(SkAlpha* SK_RESTRICT dst, 111186ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com const SkPMColor* SK_RESTRICT src, int count, 111230da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.com const SkAlpha* SK_RESTRICT aa) const { 111386ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com SkASSERT(dst && src && count >= 0); 11141447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 111586ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com if (NULL == aa) { 111686ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com for (int i = count - 1; i >= 0; --i) { 111786ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com dst[i] = SkToU8(SkGetPackedA32(src[i])); 11188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 111986ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com } else { 112086ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com for (int i = count - 1; i >= 0; --i) { 112186ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com unsigned a = aa[i]; 112286ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com if (0 != a) { 112386ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com unsigned srcA = SkGetPackedA32(src[i]); 112486ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com if (a == 0xFF) { 112586ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com dst[i] = SkToU8(srcA); 112686ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com } else { 112786ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com dst[i] = SkToU8(SkAlphaBlend(srcA, dst[i], a)); 112886ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com } 112986ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com } 11308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 113286ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com} 11330f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org#ifndef SK_IGNORE_TO_STRING 1134b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.comvoid SkSrcXfermode::toString(SkString* str) const { 1135b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com this->INHERITED::toString(str); 1136b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com} 1137b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com#endif 11381447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 113930da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.com/////////////////////////////////////////////////////////////////////////////// 114086ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com 114186ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.comclass SkDstInXfermode : public SkProcCoeffXfermode { 114286ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.compublic: 11430a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org static SkDstInXfermode* Create(const ProcCoeff& rec) { 11440a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org return SkNEW_ARGS(SkDstInXfermode, (rec)); 11450a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org } 114686ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com 114736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const override; 11481447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 11490f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org SK_TO_STRING_OVERRIDE() 11501447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 11511447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.comprivate: 11520a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org SkDstInXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kDstIn_Mode) {} 11531447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 11548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com typedef SkProcCoeffXfermode INHERITED; 11558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 11568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 115786ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.comvoid SkDstInXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 115886ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com const SkPMColor* SK_RESTRICT src, int count, 115930da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.com const SkAlpha* SK_RESTRICT aa) const { 116086ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com SkASSERT(dst && src); 11611447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 116286ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com if (count <= 0) { 116386ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com return; 116486ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com } 116549f085dddff10473b6ebf832a974288300224e60bsalomon if (aa) { 116686ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com return this->INHERITED::xfer32(dst, src, count, aa); 116786ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com } 11681447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 116986ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com do { 117086ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com unsigned a = SkGetPackedA32(*src); 117186ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com *dst = SkAlphaMulQ(*dst, SkAlpha255To256(a)); 117286ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com dst++; 117386ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com src++; 117486ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com } while (--count != 0); 117586ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com} 11761447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 11770f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org#ifndef SK_IGNORE_TO_STRING 1178b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.comvoid SkDstInXfermode::toString(SkString* str) const { 1179b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com this->INHERITED::toString(str); 1180b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com} 1181b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com#endif 1182b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com 118330da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.com/////////////////////////////////////////////////////////////////////////////// 11841447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 1185f92ace90d89cc99b34162dda26be564e34ca80efreed/* These modes can merge coverage into src-alpha 1186f92ace90d89cc99b34162dda26be564e34ca80efreed * 1187f92ace90d89cc99b34162dda26be564e34ca80efreed{ dst_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kOne_Coeff }, 1188f92ace90d89cc99b34162dda26be564e34ca80efreed{ srcover_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kISA_Coeff }, 1189f92ace90d89cc99b34162dda26be564e34ca80efreed{ dstover_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kOne_Coeff }, 1190f92ace90d89cc99b34162dda26be564e34ca80efreed{ dstout_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kISA_Coeff }, 1191f92ace90d89cc99b34162dda26be564e34ca80efreed{ srcatop_modeproc, SkXfermode::kDA_Coeff, SkXfermode::kISA_Coeff }, 1192f92ace90d89cc99b34162dda26be564e34ca80efreed{ xor_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kISA_Coeff }, 1193f92ace90d89cc99b34162dda26be564e34ca80efreed{ plus_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kOne_Coeff }, 1194f92ace90d89cc99b34162dda26be564e34ca80efreed{ screen_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kISC_Coeff }, 1195f92ace90d89cc99b34162dda26be564e34ca80efreed*/ 1196f92ace90d89cc99b34162dda26be564e34ca80efreed 1197f92ace90d89cc99b34162dda26be564e34ca80efreedstatic const float gInv255 = 0.0039215683f; // (1.0f / 255) - ULP == SkBits2Float(0x3B808080) 1198f92ace90d89cc99b34162dda26be564e34ca80efreed 1199f92ace90d89cc99b34162dda26be564e34ca80efreedstatic Sk4f ramp(const Sk4f& v0, const Sk4f& v1, const Sk4f& t) { 1200f92ace90d89cc99b34162dda26be564e34ca80efreed return v0 + (v1 - v0) * t; 1201f92ace90d89cc99b34162dda26be564e34ca80efreed} 1202f92ace90d89cc99b34162dda26be564e34ca80efreed 1203f92ace90d89cc99b34162dda26be564e34ca80efreedstatic Sk4f clamp_255(const Sk4f& value) { 1204f8f5478f92d6bce30448203857156a4cda4a13d7reed return Sk4f::Min(Sk4f(255), value); 1205f8f5478f92d6bce30448203857156a4cda4a13d7reed} 1206f8f5478f92d6bce30448203857156a4cda4a13d7reed 1207f8f5478f92d6bce30448203857156a4cda4a13d7reedstatic Sk4f clamp_0_255(const Sk4f& value) { 1208f8f5478f92d6bce30448203857156a4cda4a13d7reed return Sk4f::Max(Sk4f(0), Sk4f::Min(Sk4f(255), value)); 1209f92ace90d89cc99b34162dda26be564e34ca80efreed} 1210f92ace90d89cc99b34162dda26be564e34ca80efreed 1211f92ace90d89cc99b34162dda26be564e34ca80efreed/** 1212f92ace90d89cc99b34162dda26be564e34ca80efreed * Some modes can, due to very slight numerical error, generate "invalid" pmcolors... 1213f92ace90d89cc99b34162dda26be564e34ca80efreed * 1214f92ace90d89cc99b34162dda26be564e34ca80efreed * e.g. 1215f92ace90d89cc99b34162dda26be564e34ca80efreed * alpha = 100.9999 1216f92ace90d89cc99b34162dda26be564e34ca80efreed * red = 101 1217f92ace90d89cc99b34162dda26be564e34ca80efreed * 1218f92ace90d89cc99b34162dda26be564e34ca80efreed * or 1219f92ace90d89cc99b34162dda26be564e34ca80efreed * alpha = 255.0001 1220f92ace90d89cc99b34162dda26be564e34ca80efreed * 1221f92ace90d89cc99b34162dda26be564e34ca80efreed * If we know we're going to write-out the values as bytes, we can relax these somewhat, 1222f92ace90d89cc99b34162dda26be564e34ca80efreed * since we only really need to enforce that the bytes are valid premul... 1223f92ace90d89cc99b34162dda26be564e34ca80efreed * 1224f92ace90d89cc99b34162dda26be564e34ca80efreed * To that end, this method asserts that the resulting pmcolor will be valid, but does not call 1225f92ace90d89cc99b34162dda26be564e34ca80efreed * SkPMFloat::isValid(), as that would fire sometimes, but not result in a bad pixel. 1226f92ace90d89cc99b34162dda26be564e34ca80efreed */ 1227f92ace90d89cc99b34162dda26be564e34ca80efreedstatic inline SkPMFloat check_as_pmfloat(const Sk4f& value) { 1228f92ace90d89cc99b34162dda26be564e34ca80efreed SkPMFloat pm = value; 1229f92ace90d89cc99b34162dda26be564e34ca80efreed#ifdef SK_DEBUG 12303d626834b4b5ee2d6dda34da365dfe40520253aamtklein (void)pm.round(); 1231f92ace90d89cc99b34162dda26be564e34ca80efreed#endif 1232f92ace90d89cc99b34162dda26be564e34ca80efreed return pm; 1233f92ace90d89cc99b34162dda26be564e34ca80efreed} 1234f92ace90d89cc99b34162dda26be564e34ca80efreed 1235f92ace90d89cc99b34162dda26be564e34ca80efreed// kSrcATop_Mode, //!< [Da, Sc * Da + (1 - Sa) * Dc] 1236f92ace90d89cc99b34162dda26be564e34ca80efreedstruct SrcATop4f { 1237f92ace90d89cc99b34162dda26be564e34ca80efreed static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { 1238f92ace90d89cc99b34162dda26be564e34ca80efreed const Sk4f inv255(gInv255); 12397792dbf7ea089b3bcb81792a3ecda8a6f8b421e7mtklein return check_as_pmfloat(dst + (src * Sk4f(dst.a()) - dst * Sk4f(src.a())) * inv255); 1240f92ace90d89cc99b34162dda26be564e34ca80efreed } 12412d8d33e9e825f9919875be64a71b746189b385bemtklein static Sk4px Xfer(const Sk4px& src, const Sk4px& dst) { 12422d8d33e9e825f9919875be64a71b746189b385bemtklein return Sk4px::Wide(src.mulWiden(dst.alphas()) + dst.mulWiden(src.alphas().inv())) 12432d8d33e9e825f9919875be64a71b746189b385bemtklein .div255RoundNarrow(); 12442d8d33e9e825f9919875be64a71b746189b385bemtklein } 1245f92ace90d89cc99b34162dda26be564e34ca80efreed static const bool kFoldCoverageIntoSrcAlpha = true; 1246f92ace90d89cc99b34162dda26be564e34ca80efreed static const SkXfermode::Mode kMode = SkXfermode::kSrcATop_Mode; 1247f92ace90d89cc99b34162dda26be564e34ca80efreed}; 1248f92ace90d89cc99b34162dda26be564e34ca80efreed 1249f92ace90d89cc99b34162dda26be564e34ca80efreed// kDstATop_Mode, //!< [Sa, Sa * Dc + Sc * (1 - Da)] 1250f92ace90d89cc99b34162dda26be564e34ca80efreedstruct DstATop4f { 1251f92ace90d89cc99b34162dda26be564e34ca80efreed static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { 12522d8d33e9e825f9919875be64a71b746189b385bemtklein return SrcATop4f::Xfer(dst, src); 12532d8d33e9e825f9919875be64a71b746189b385bemtklein } 12542d8d33e9e825f9919875be64a71b746189b385bemtklein static Sk4px Xfer(const Sk4px& src, const Sk4px& dst) { 12552d8d33e9e825f9919875be64a71b746189b385bemtklein return SrcATop4f::Xfer(dst, src); 1256f92ace90d89cc99b34162dda26be564e34ca80efreed } 1257f92ace90d89cc99b34162dda26be564e34ca80efreed static const bool kFoldCoverageIntoSrcAlpha = false; 1258f92ace90d89cc99b34162dda26be564e34ca80efreed static const SkXfermode::Mode kMode = SkXfermode::kDstATop_Mode; 1259f92ace90d89cc99b34162dda26be564e34ca80efreed}; 1260f92ace90d89cc99b34162dda26be564e34ca80efreed 1261f92ace90d89cc99b34162dda26be564e34ca80efreed// kXor_Mode [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc] 1262f92ace90d89cc99b34162dda26be564e34ca80efreedstruct Xor4f { 1263f92ace90d89cc99b34162dda26be564e34ca80efreed static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { 1264f92ace90d89cc99b34162dda26be564e34ca80efreed const Sk4f inv255(gInv255); 12657792dbf7ea089b3bcb81792a3ecda8a6f8b421e7mtklein return check_as_pmfloat(src + dst - (src * Sk4f(dst.a()) + dst * Sk4f(src.a())) * inv255); 1266f92ace90d89cc99b34162dda26be564e34ca80efreed } 12672d8d33e9e825f9919875be64a71b746189b385bemtklein static Sk4px Xfer(const Sk4px& src, const Sk4px& dst) { 12682d8d33e9e825f9919875be64a71b746189b385bemtklein return Sk4px::Wide(src.mulWiden(dst.alphas().inv()) + dst.mulWiden(src.alphas().inv())) 12692d8d33e9e825f9919875be64a71b746189b385bemtklein .div255RoundNarrow(); 12702d8d33e9e825f9919875be64a71b746189b385bemtklein } 1271f92ace90d89cc99b34162dda26be564e34ca80efreed static const bool kFoldCoverageIntoSrcAlpha = true; 1272f92ace90d89cc99b34162dda26be564e34ca80efreed static const SkXfermode::Mode kMode = SkXfermode::kXor_Mode; 1273f92ace90d89cc99b34162dda26be564e34ca80efreed}; 1274f92ace90d89cc99b34162dda26be564e34ca80efreed 1275f92ace90d89cc99b34162dda26be564e34ca80efreed// kPlus_Mode [Sa + Da, Sc + Dc] 1276f92ace90d89cc99b34162dda26be564e34ca80efreedstruct Plus4f { 1277f92ace90d89cc99b34162dda26be564e34ca80efreed static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { 12787792dbf7ea089b3bcb81792a3ecda8a6f8b421e7mtklein return check_as_pmfloat(clamp_255(src + dst)); 1279f92ace90d89cc99b34162dda26be564e34ca80efreed } 12806cbf18c70bf99f58b2bb1c49cdf8d41be561fee4mtklein static Sk4px Xfer(const Sk4px& src, const Sk4px& dst) { 12816cbf18c70bf99f58b2bb1c49cdf8d41be561fee4mtklein return src.saturatedAdd(dst); 12826cbf18c70bf99f58b2bb1c49cdf8d41be561fee4mtklein } 12836cbf18c70bf99f58b2bb1c49cdf8d41be561fee4mtklein static const bool kFoldCoverageIntoSrcAlpha = false; 1284f92ace90d89cc99b34162dda26be564e34ca80efreed static const SkXfermode::Mode kMode = SkXfermode::kPlus_Mode; 1285f92ace90d89cc99b34162dda26be564e34ca80efreed}; 1286f92ace90d89cc99b34162dda26be564e34ca80efreed 1287f92ace90d89cc99b34162dda26be564e34ca80efreed// kModulate_Mode [Sa * Da, Sc * Dc] 1288f92ace90d89cc99b34162dda26be564e34ca80efreedstruct Modulate4f { 1289f92ace90d89cc99b34162dda26be564e34ca80efreed static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { 1290f92ace90d89cc99b34162dda26be564e34ca80efreed const Sk4f inv255(gInv255); 12917792dbf7ea089b3bcb81792a3ecda8a6f8b421e7mtklein return check_as_pmfloat(src * dst * inv255); 1292f92ace90d89cc99b34162dda26be564e34ca80efreed } 12936cbf18c70bf99f58b2bb1c49cdf8d41be561fee4mtklein static Sk4px Xfer(const Sk4px& src, const Sk4px& dst) { 12946cbf18c70bf99f58b2bb1c49cdf8d41be561fee4mtklein return src.mulWiden(dst).div255RoundNarrow(); 12956cbf18c70bf99f58b2bb1c49cdf8d41be561fee4mtklein } 1296f92ace90d89cc99b34162dda26be564e34ca80efreed static const bool kFoldCoverageIntoSrcAlpha = false; 1297f92ace90d89cc99b34162dda26be564e34ca80efreed static const SkXfermode::Mode kMode = SkXfermode::kModulate_Mode; 1298f92ace90d89cc99b34162dda26be564e34ca80efreed}; 1299f92ace90d89cc99b34162dda26be564e34ca80efreed 1300f92ace90d89cc99b34162dda26be564e34ca80efreed// kScreen_Mode [S + D - S * D] 1301f92ace90d89cc99b34162dda26be564e34ca80efreedstruct Screen4f { 1302f92ace90d89cc99b34162dda26be564e34ca80efreed static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { 1303f92ace90d89cc99b34162dda26be564e34ca80efreed const Sk4f inv255(gInv255); 13047792dbf7ea089b3bcb81792a3ecda8a6f8b421e7mtklein return check_as_pmfloat(src + dst - src * dst * inv255); 1305f92ace90d89cc99b34162dda26be564e34ca80efreed } 13066cbf18c70bf99f58b2bb1c49cdf8d41be561fee4mtklein static Sk4px Xfer(const Sk4px& src, const Sk4px& dst) { 13076cbf18c70bf99f58b2bb1c49cdf8d41be561fee4mtklein // Doing the math as S + (1-S)*D or S + (D - S*D) means the add and subtract can be done 13082d8d33e9e825f9919875be64a71b746189b385bemtklein // in 8-bit space without overflow. S + (1-S)*D is a touch faster because inv() is cheap. 13092d8d33e9e825f9919875be64a71b746189b385bemtklein return src + src.inv().mulWiden(dst).div255RoundNarrow(); 13106cbf18c70bf99f58b2bb1c49cdf8d41be561fee4mtklein } 1311f92ace90d89cc99b34162dda26be564e34ca80efreed static const bool kFoldCoverageIntoSrcAlpha = true; 1312f92ace90d89cc99b34162dda26be564e34ca80efreed static const SkXfermode::Mode kMode = SkXfermode::kScreen_Mode; 1313f92ace90d89cc99b34162dda26be564e34ca80efreed}; 1314f92ace90d89cc99b34162dda26be564e34ca80efreed 1315f8f5478f92d6bce30448203857156a4cda4a13d7reedstruct Multiply4f { 1316f8f5478f92d6bce30448203857156a4cda4a13d7reed static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { 1317f8f5478f92d6bce30448203857156a4cda4a13d7reed const Sk4f inv255(gInv255); 1318f8f5478f92d6bce30448203857156a4cda4a13d7reed Sk4f sa = Sk4f(src.a()); 1319f8f5478f92d6bce30448203857156a4cda4a13d7reed Sk4f da = Sk4f(dst.a()); 1320f8f5478f92d6bce30448203857156a4cda4a13d7reed Sk4f sc = src; 1321f8f5478f92d6bce30448203857156a4cda4a13d7reed Sk4f dc = dst; 1322f8f5478f92d6bce30448203857156a4cda4a13d7reed Sk4f rc = sc + dc + (sc * (dc - da) - dc * sa) * inv255; 1323f8f5478f92d6bce30448203857156a4cda4a13d7reed // ra = srcover(sa, da), but the calc for rc happens to accomplish this for us 1324f8f5478f92d6bce30448203857156a4cda4a13d7reed return check_as_pmfloat(clamp_0_255(rc)); 1325f8f5478f92d6bce30448203857156a4cda4a13d7reed } 13262d8d33e9e825f9919875be64a71b746189b385bemtklein static Sk4px Xfer(const Sk4px& src, const Sk4px& dst) { 13272d8d33e9e825f9919875be64a71b746189b385bemtklein return Sk4px::Wide(src.mulWiden(dst.alphas().inv()) + 13282d8d33e9e825f9919875be64a71b746189b385bemtklein dst.mulWiden(src.alphas().inv()) + 13292d8d33e9e825f9919875be64a71b746189b385bemtklein src.mulWiden(dst)) 13302d8d33e9e825f9919875be64a71b746189b385bemtklein .div255RoundNarrow(); 13312d8d33e9e825f9919875be64a71b746189b385bemtklein } 1332f8f5478f92d6bce30448203857156a4cda4a13d7reed static const bool kFoldCoverageIntoSrcAlpha = false; 1333f8f5478f92d6bce30448203857156a4cda4a13d7reed static const SkXfermode::Mode kMode = SkXfermode::kMultiply_Mode; 1334f8f5478f92d6bce30448203857156a4cda4a13d7reed}; 1335f8f5478f92d6bce30448203857156a4cda4a13d7reed 13360135a41e095a433414e21e37b277dab7dcbec373mtklein// [ sa + da - sa*da, sc + dc - 2*min(sc*da, dc*sa) ] (And notice sa*da == min(sa*da, da*sa).) 133792dabe7421aa6ba4149901108d8ab72956f67eebreedstruct Difference4f { 133892dabe7421aa6ba4149901108d8ab72956f67eebreed static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { 133992dabe7421aa6ba4149901108d8ab72956f67eebreed const Sk4f inv255(gInv255); 134092dabe7421aa6ba4149901108d8ab72956f67eebreed Sk4f sa = Sk4f(src.a()); 134192dabe7421aa6ba4149901108d8ab72956f67eebreed Sk4f da = Sk4f(dst.a()); 134292dabe7421aa6ba4149901108d8ab72956f67eebreed Sk4f sc = src; 134392dabe7421aa6ba4149901108d8ab72956f67eebreed Sk4f dc = dst; 134492dabe7421aa6ba4149901108d8ab72956f67eebreed Sk4f min = Sk4f::Min(sc * da, dc * sa) * inv255; 134592dabe7421aa6ba4149901108d8ab72956f67eebreed Sk4f ra = sc + dc - min; 13466cad1da6ef6a41c25258a42cd36e9a591a1cc076reed return check_as_pmfloat(ra - min * SkPMFloat(0, 1, 1, 1)); 134792dabe7421aa6ba4149901108d8ab72956f67eebreed } 13480135a41e095a433414e21e37b277dab7dcbec373mtklein static Sk4px Xfer(const Sk4px& src, const Sk4px& dst) { 13490135a41e095a433414e21e37b277dab7dcbec373mtklein auto m = Sk4px::Wide(Sk16h::Min(src.mulWiden(dst.alphas()), dst.mulWiden(src.alphas()))) 13500135a41e095a433414e21e37b277dab7dcbec373mtklein .div255RoundNarrow(); 13510135a41e095a433414e21e37b277dab7dcbec373mtklein // There's no chance of underflow, and if we subtract m before adding src+dst, no overflow. 13520135a41e095a433414e21e37b277dab7dcbec373mtklein return (src - m) + (dst - m.zeroAlphas()); 13530135a41e095a433414e21e37b277dab7dcbec373mtklein } 135492dabe7421aa6ba4149901108d8ab72956f67eebreed static const bool kFoldCoverageIntoSrcAlpha = false; 135592dabe7421aa6ba4149901108d8ab72956f67eebreed static const SkXfermode::Mode kMode = SkXfermode::kDifference_Mode; 135692dabe7421aa6ba4149901108d8ab72956f67eebreed}; 135792dabe7421aa6ba4149901108d8ab72956f67eebreed 13580135a41e095a433414e21e37b277dab7dcbec373mtklein// [ sa + da - sa*da, sc + dc - 2*sc*dc ] 135992dabe7421aa6ba4149901108d8ab72956f67eebreedstruct Exclusion4f { 136092dabe7421aa6ba4149901108d8ab72956f67eebreed static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { 136192dabe7421aa6ba4149901108d8ab72956f67eebreed const Sk4f inv255(gInv255); 136292dabe7421aa6ba4149901108d8ab72956f67eebreed Sk4f sc = src; 136392dabe7421aa6ba4149901108d8ab72956f67eebreed Sk4f dc = dst; 136492dabe7421aa6ba4149901108d8ab72956f67eebreed Sk4f prod = sc * dc * inv255; 136592dabe7421aa6ba4149901108d8ab72956f67eebreed Sk4f ra = sc + dc - prod; 13666cad1da6ef6a41c25258a42cd36e9a591a1cc076reed return check_as_pmfloat(ra - prod * SkPMFloat(0, 1, 1, 1)); 136792dabe7421aa6ba4149901108d8ab72956f67eebreed } 13680135a41e095a433414e21e37b277dab7dcbec373mtklein static Sk4px Xfer(const Sk4px& src, const Sk4px& dst) { 13690135a41e095a433414e21e37b277dab7dcbec373mtklein auto p = src.mulWiden(dst).div255RoundNarrow(); 13700135a41e095a433414e21e37b277dab7dcbec373mtklein // There's no chance of underflow, and if we subtract p before adding src+dst, no overflow. 13710135a41e095a433414e21e37b277dab7dcbec373mtklein return (src - p) + (dst - p.zeroAlphas()); 13720135a41e095a433414e21e37b277dab7dcbec373mtklein } 137392dabe7421aa6ba4149901108d8ab72956f67eebreed static const bool kFoldCoverageIntoSrcAlpha = false; 137492dabe7421aa6ba4149901108d8ab72956f67eebreed static const SkXfermode::Mode kMode = SkXfermode::kExclusion_Mode; 137592dabe7421aa6ba4149901108d8ab72956f67eebreed}; 137692dabe7421aa6ba4149901108d8ab72956f67eebreed 1377f92ace90d89cc99b34162dda26be564e34ca80efreedtemplate <typename ProcType> 1378f92ace90d89cc99b34162dda26be564e34ca80efreedclass SkT4fXfermode : public SkProcCoeffXfermode { 1379f92ace90d89cc99b34162dda26be564e34ca80efreedpublic: 1380f92ace90d89cc99b34162dda26be564e34ca80efreed static SkXfermode* Create(const ProcCoeff& rec) { 1381f92ace90d89cc99b34162dda26be564e34ca80efreed return SkNEW_ARGS(SkT4fXfermode, (rec)); 1382f92ace90d89cc99b34162dda26be564e34ca80efreed } 13833d626834b4b5ee2d6dda34da365dfe40520253aamtklein 1384f92ace90d89cc99b34162dda26be564e34ca80efreed void xfer32(SkPMColor dst[], const SkPMColor src[], int n, const SkAlpha aa[]) const override { 1385f92ace90d89cc99b34162dda26be564e34ca80efreed if (NULL == aa) { 1386f92ace90d89cc99b34162dda26be564e34ca80efreed for (int i = 0; i < n; ++i) { 13876cad1da6ef6a41c25258a42cd36e9a591a1cc076reed dst[i] = ProcType::Xfer(SkPMFloat(src[i]), SkPMFloat(dst[i])).round(); 1388f92ace90d89cc99b34162dda26be564e34ca80efreed } 1389f92ace90d89cc99b34162dda26be564e34ca80efreed } else { 1390f92ace90d89cc99b34162dda26be564e34ca80efreed for (int i = 0; i < n; ++i) { 1391f92ace90d89cc99b34162dda26be564e34ca80efreed const Sk4f aa4 = Sk4f(aa[i] * gInv255); 1392f92ace90d89cc99b34162dda26be564e34ca80efreed SkPMFloat dstF(dst[i]); 1393f92ace90d89cc99b34162dda26be564e34ca80efreed SkPMFloat srcF(src[i]); 1394f92ace90d89cc99b34162dda26be564e34ca80efreed Sk4f res; 1395f92ace90d89cc99b34162dda26be564e34ca80efreed if (ProcType::kFoldCoverageIntoSrcAlpha) { 1396f92ace90d89cc99b34162dda26be564e34ca80efreed Sk4f src4 = srcF; 1397f92ace90d89cc99b34162dda26be564e34ca80efreed res = ProcType::Xfer(src4 * aa4, dstF); 1398f92ace90d89cc99b34162dda26be564e34ca80efreed } else { 1399f92ace90d89cc99b34162dda26be564e34ca80efreed res = ramp(dstF, ProcType::Xfer(srcF, dstF), aa4); 1400f92ace90d89cc99b34162dda26be564e34ca80efreed } 14013d626834b4b5ee2d6dda34da365dfe40520253aamtklein dst[i] = SkPMFloat(res).round(); 1402f92ace90d89cc99b34162dda26be564e34ca80efreed } 1403f92ace90d89cc99b34162dda26be564e34ca80efreed } 1404f92ace90d89cc99b34162dda26be564e34ca80efreed } 14053d626834b4b5ee2d6dda34da365dfe40520253aamtklein 1406f92ace90d89cc99b34162dda26be564e34ca80efreedprivate: 1407f92ace90d89cc99b34162dda26be564e34ca80efreed SkT4fXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, ProcType::kMode) {} 14083d626834b4b5ee2d6dda34da365dfe40520253aamtklein 1409f92ace90d89cc99b34162dda26be564e34ca80efreed typedef SkProcCoeffXfermode INHERITED; 1410f92ace90d89cc99b34162dda26be564e34ca80efreed}; 14116cbf18c70bf99f58b2bb1c49cdf8d41be561fee4mtklein 14126cbf18c70bf99f58b2bb1c49cdf8d41be561fee4mtkleintemplate <typename ProcType> 14136cbf18c70bf99f58b2bb1c49cdf8d41be561fee4mtkleinclass SkT4pxXfermode : public SkProcCoeffXfermode { 14146cbf18c70bf99f58b2bb1c49cdf8d41be561fee4mtkleinpublic: 14156cbf18c70bf99f58b2bb1c49cdf8d41be561fee4mtklein static SkXfermode* Create(const ProcCoeff& rec) { 14166cbf18c70bf99f58b2bb1c49cdf8d41be561fee4mtklein return SkNEW_ARGS(SkT4pxXfermode, (rec)); 14176cbf18c70bf99f58b2bb1c49cdf8d41be561fee4mtklein } 14186cbf18c70bf99f58b2bb1c49cdf8d41be561fee4mtklein 14196cbf18c70bf99f58b2bb1c49cdf8d41be561fee4mtklein void xfer32(SkPMColor dst[], const SkPMColor src[], int n, const SkAlpha aa[]) const override { 14206cbf18c70bf99f58b2bb1c49cdf8d41be561fee4mtklein if (NULL == aa) { 14216cbf18c70bf99f58b2bb1c49cdf8d41be561fee4mtklein Sk4px::MapDstSrc(n, dst, src, [&](const Sk4px& dst4, const Sk4px& src4) { 14226cbf18c70bf99f58b2bb1c49cdf8d41be561fee4mtklein return ProcType::Xfer(src4, dst4); 14236cbf18c70bf99f58b2bb1c49cdf8d41be561fee4mtklein }); 14246cbf18c70bf99f58b2bb1c49cdf8d41be561fee4mtklein } else { 14256cbf18c70bf99f58b2bb1c49cdf8d41be561fee4mtklein Sk4px::MapDstSrcAlpha(n, dst, src, aa, 14266cbf18c70bf99f58b2bb1c49cdf8d41be561fee4mtklein [&](const Sk4px& dst4, const Sk4px& src4, const Sk16b& alpha) { 14276cbf18c70bf99f58b2bb1c49cdf8d41be561fee4mtklein // We can't exploit kFoldCoverageIntoSrcAlpha. That requires >=24-bit intermediates. 14286cbf18c70bf99f58b2bb1c49cdf8d41be561fee4mtklein Sk4px res4 = ProcType::Xfer(src4, dst4); 14290135a41e095a433414e21e37b277dab7dcbec373mtklein return Sk4px::Wide(res4.mulWiden(alpha) + dst4.mulWiden(Sk4px(alpha).inv())) 14306cbf18c70bf99f58b2bb1c49cdf8d41be561fee4mtklein .div255RoundNarrow(); 14316cbf18c70bf99f58b2bb1c49cdf8d41be561fee4mtklein }); 14326cbf18c70bf99f58b2bb1c49cdf8d41be561fee4mtklein } 14336cbf18c70bf99f58b2bb1c49cdf8d41be561fee4mtklein } 14346cbf18c70bf99f58b2bb1c49cdf8d41be561fee4mtklein 14356cbf18c70bf99f58b2bb1c49cdf8d41be561fee4mtkleinprivate: 14366cbf18c70bf99f58b2bb1c49cdf8d41be561fee4mtklein SkT4pxXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, ProcType::kMode) {} 14376cbf18c70bf99f58b2bb1c49cdf8d41be561fee4mtklein 14386cbf18c70bf99f58b2bb1c49cdf8d41be561fee4mtklein typedef SkProcCoeffXfermode INHERITED; 14396cbf18c70bf99f58b2bb1c49cdf8d41be561fee4mtklein}; 1440f92ace90d89cc99b34162dda26be564e34ca80efreed 1441f92ace90d89cc99b34162dda26be564e34ca80efreed/////////////////////////////////////////////////////////////////////////////// 1442f92ace90d89cc99b34162dda26be564e34ca80efreed 144386ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.comclass SkDstOutXfermode : public SkProcCoeffXfermode { 144486ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.compublic: 14450a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org static SkDstOutXfermode* Create(const ProcCoeff& rec) { 14460a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org return SkNEW_ARGS(SkDstOutXfermode, (rec)); 14470a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org } 144886ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com 144936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const override; 14501447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 14510f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org SK_TO_STRING_OVERRIDE() 14521447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 14531447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.comprivate: 14540a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org SkDstOutXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kDstOut_Mode) {} 14551447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 14568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com typedef SkProcCoeffXfermode INHERITED; 14578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 14588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 145986ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.comvoid SkDstOutXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 146086ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com const SkPMColor* SK_RESTRICT src, int count, 146130da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.com const SkAlpha* SK_RESTRICT aa) const { 146286ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com SkASSERT(dst && src); 146386ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com 146486ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com if (count <= 0) { 146586ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com return; 146686ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com } 146749f085dddff10473b6ebf832a974288300224e60bsalomon if (aa) { 146886ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com return this->INHERITED::xfer32(dst, src, count, aa); 146986ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com } 147086ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com 147186ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com do { 147286ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com unsigned a = SkGetPackedA32(*src); 147386ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com *dst = SkAlphaMulQ(*dst, SkAlpha255To256(255 - a)); 147486ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com dst++; 147586ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com src++; 147686ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com } while (--count != 0); 147786ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com} 147886ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com 14790f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org#ifndef SK_IGNORE_TO_STRING 1480b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.comvoid SkDstOutXfermode::toString(SkString* str) const { 1481b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com this->INHERITED::toString(str); 1482b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com} 1483b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com#endif 1484b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com 14858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 14868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 148797de357270e54be53acb17e1cb4b4d5e25bacc01commit-bot@chromium.orgextern SkProcCoeffXfermode* SkPlatformXfermodeFactory(const ProcCoeff& rec, SkXfermode::Mode mode); 1488d611864e679a58865b111e74fe7ac919cba42163commit-bot@chromium.orgextern SkXfermodeProc SkPlatformXfermodeProcFactory(SkXfermode::Mode mode); 1489df187c7eb27d7616b75d91f3329deb97c4cd6de2commit-bot@chromium.org 149097de357270e54be53acb17e1cb4b4d5e25bacc01commit-bot@chromium.org// Technically, can't be static and passed as a template parameter. So we use anonymous namespace. 149197de357270e54be53acb17e1cb4b4d5e25bacc01commit-bot@chromium.orgnamespace { 149297de357270e54be53acb17e1cb4b4d5e25bacc01commit-bot@chromium.orgSkXfermode* create_mode(int iMode) { 149397de357270e54be53acb17e1cb4b4d5e25bacc01commit-bot@chromium.org SkXfermode::Mode mode = (SkXfermode::Mode)iMode; 1494140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org 1495140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org ProcCoeff rec = gProcCoeffs[mode]; 1496140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org SkXfermodeProc pp = SkPlatformXfermodeProcFactory(mode); 1497140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org if (pp != NULL) { 1498140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org rec.fProc = pp; 1499140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org } 1500140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org 150104d24a3f86b6f2382e5c6ffaf161ffc734a4d02amtklein#if defined(SK_4PX_XFERMODES_ARE_FAST) && !defined(SK_PREFER_LEGACY_FLOAT_XFERMODES) 1502f92ace90d89cc99b34162dda26be564e34ca80efreed switch (mode) { 15030135a41e095a433414e21e37b277dab7dcbec373mtklein case SkXfermode::kSrcATop_Mode: return SkT4pxXfermode<SrcATop4f>::Create(rec); 15040135a41e095a433414e21e37b277dab7dcbec373mtklein case SkXfermode::kDstATop_Mode: return SkT4pxXfermode<DstATop4f>::Create(rec); 15050135a41e095a433414e21e37b277dab7dcbec373mtklein case SkXfermode::kXor_Mode: return SkT4pxXfermode<Xor4f>::Create(rec); 15060135a41e095a433414e21e37b277dab7dcbec373mtklein case SkXfermode::kPlus_Mode: return SkT4pxXfermode<Plus4f>::Create(rec); 15070135a41e095a433414e21e37b277dab7dcbec373mtklein case SkXfermode::kModulate_Mode: return SkT4pxXfermode<Modulate4f>::Create(rec); 15080135a41e095a433414e21e37b277dab7dcbec373mtklein case SkXfermode::kScreen_Mode: return SkT4pxXfermode<Screen4f>::Create(rec); 15090135a41e095a433414e21e37b277dab7dcbec373mtklein case SkXfermode::kMultiply_Mode: return SkT4pxXfermode<Multiply4f>::Create(rec); 15100135a41e095a433414e21e37b277dab7dcbec373mtklein case SkXfermode::kDifference_Mode: return SkT4pxXfermode<Difference4f>::Create(rec); 15110135a41e095a433414e21e37b277dab7dcbec373mtklein case SkXfermode::kExclusion_Mode: return SkT4pxXfermode<Exclusion4f>::Create(rec); 151204d24a3f86b6f2382e5c6ffaf161ffc734a4d02amtklein default: break; 1513f92ace90d89cc99b34162dda26be564e34ca80efreed } 151404d24a3f86b6f2382e5c6ffaf161ffc734a4d02amtklein#endif 151504d24a3f86b6f2382e5c6ffaf161ffc734a4d02amtklein 151604d24a3f86b6f2382e5c6ffaf161ffc734a4d02amtklein#if defined(SK_4F_XFERMODES_ARE_FAST) 151704d24a3f86b6f2382e5c6ffaf161ffc734a4d02amtklein switch (mode) { 151804d24a3f86b6f2382e5c6ffaf161ffc734a4d02amtklein case SkXfermode::kSrcATop_Mode: return SkT4fXfermode<SrcATop4f>::Create(rec); 151904d24a3f86b6f2382e5c6ffaf161ffc734a4d02amtklein case SkXfermode::kDstATop_Mode: return SkT4fXfermode<DstATop4f>::Create(rec); 152004d24a3f86b6f2382e5c6ffaf161ffc734a4d02amtklein case SkXfermode::kXor_Mode: return SkT4fXfermode<Xor4f>::Create(rec); 152104d24a3f86b6f2382e5c6ffaf161ffc734a4d02amtklein case SkXfermode::kPlus_Mode: return SkT4fXfermode<Plus4f>::Create(rec); 152204d24a3f86b6f2382e5c6ffaf161ffc734a4d02amtklein case SkXfermode::kModulate_Mode: return SkT4fXfermode<Modulate4f>::Create(rec); 152304d24a3f86b6f2382e5c6ffaf161ffc734a4d02amtklein case SkXfermode::kScreen_Mode: return SkT4fXfermode<Screen4f>::Create(rec); 152404d24a3f86b6f2382e5c6ffaf161ffc734a4d02amtklein case SkXfermode::kMultiply_Mode: return SkT4fXfermode<Multiply4f>::Create(rec); 152504d24a3f86b6f2382e5c6ffaf161ffc734a4d02amtklein case SkXfermode::kDifference_Mode: return SkT4fXfermode<Difference4f>::Create(rec); 152604d24a3f86b6f2382e5c6ffaf161ffc734a4d02amtklein case SkXfermode::kExclusion_Mode: return SkT4fXfermode<Exclusion4f>::Create(rec); 152704d24a3f86b6f2382e5c6ffaf161ffc734a4d02amtklein default: break; 1528f92ace90d89cc99b34162dda26be564e34ca80efreed } 1529f92ace90d89cc99b34162dda26be564e34ca80efreed#endif 1530f92ace90d89cc99b34162dda26be564e34ca80efreed 153104d24a3f86b6f2382e5c6ffaf161ffc734a4d02amtklein SkXfermode* xfer = NULL; 153204d24a3f86b6f2382e5c6ffaf161ffc734a4d02amtklein 1533140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org // check if we have a platform optim for that 1534140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org SkProcCoeffXfermode* xfm = SkPlatformXfermodeFactory(rec, mode); 1535140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org if (xfm != NULL) { 1536140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org xfer = xfm; 1537140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org } else { 1538140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org // All modes can in theory be represented by the ProcCoeff rec, since 1539140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org // it contains function ptrs. However, a few modes are both simple and 1540140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org // commonly used, so we call those out for their own subclasses here. 1541140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org switch (mode) { 1542140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org case SkXfermode::kClear_Mode: 1543140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org xfer = SkClearXfermode::Create(rec); 1544140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org break; 1545140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org case SkXfermode::kSrc_Mode: 1546140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org xfer = SkSrcXfermode::Create(rec); 1547140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org break; 1548140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org case SkXfermode::kSrcOver_Mode: 1549140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org SkASSERT(false); // should not land here 1550140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org break; 1551140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org case SkXfermode::kDstIn_Mode: 1552140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org xfer = SkDstInXfermode::Create(rec); 1553140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org break; 1554140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org case SkXfermode::kDstOut_Mode: 1555140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org xfer = SkDstOutXfermode::Create(rec); 1556140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org break; 1557140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org default: 1558140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org // no special-case, just rely in the rec and its function-ptrs 15599fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed xfer = SkNEW_ARGS(SkProcCoeffXfermode, (rec, mode)); 1560140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org break; 1561140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org } 1562140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org } 156397de357270e54be53acb17e1cb4b4d5e25bacc01commit-bot@chromium.org return xfer; 1564140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org} 156597de357270e54be53acb17e1cb4b4d5e25bacc01commit-bot@chromium.org} // namespace 156697de357270e54be53acb17e1cb4b4d5e25bacc01commit-bot@chromium.org 1567148ec59001ca7d7e54aec580a048c6dd2a085991mtkleinSK_DECLARE_STATIC_LAZY_PTR_ARRAY(SkXfermode, cached, SkXfermode::kLastMode + 1, create_mode); 1568140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org 1569a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.comSkXfermode* SkXfermode::Create(Mode mode) { 1570a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount); 15718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 157286490573b5cba554a27637e22485455a7b133de7commit-bot@chromium.org if ((unsigned)mode >= kModeCount) { 157386490573b5cba554a27637e22485455a7b133de7commit-bot@chromium.org // report error 157486490573b5cba554a27637e22485455a7b133de7commit-bot@chromium.org return NULL; 157586490573b5cba554a27637e22485455a7b133de7commit-bot@chromium.org } 1576c0d4aa2088a0788f9df221497945d2ba1b342f44reed@google.com 157797de357270e54be53acb17e1cb4b4d5e25bacc01commit-bot@chromium.org // Skia's "default" mode is srcover. NULL in SkPaint is interpreted as srcover 157886490573b5cba554a27637e22485455a7b133de7commit-bot@chromium.org // so we can just return NULL from the factory. 157986490573b5cba554a27637e22485455a7b133de7commit-bot@chromium.org if (kSrcOver_Mode == mode) { 158086490573b5cba554a27637e22485455a7b133de7commit-bot@chromium.org return NULL; 158186490573b5cba554a27637e22485455a7b133de7commit-bot@chromium.org } 158286490573b5cba554a27637e22485455a7b133de7commit-bot@chromium.org 158397de357270e54be53acb17e1cb4b4d5e25bacc01commit-bot@chromium.org return SkSafeRef(cached[mode]); 15848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 15858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 158643c50c8c77df82c5cffb55cae2d386e59802b88freed@google.comSkXfermodeProc SkXfermode::GetProc(Mode mode) { 158743c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com SkXfermodeProc proc = NULL; 158843c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com if ((unsigned)mode < kModeCount) { 158943c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com proc = gProcCoeffs[mode].fProc; 159043c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com } 159143c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com return proc; 159243c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com} 159343c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com 159443c50c8c77df82c5cffb55cae2d386e59802b88freed@google.combool SkXfermode::ModeAsCoeff(Mode mode, Coeff* src, Coeff* dst) { 159543c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount); 15961447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 159743c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com if ((unsigned)mode >= (unsigned)kModeCount) { 159843c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com // illegal mode parameter 159943c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com return false; 160043c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com } 16011447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 160243c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com const ProcCoeff& rec = gProcCoeffs[mode]; 16031447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 160443c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com if (CANNOT_USE_COEFF == rec.fSC) { 160543c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com return false; 160643c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com } 16071447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 160843c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com SkASSERT(CANNOT_USE_COEFF != rec.fDC); 160943c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com if (src) { 161043c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com *src = rec.fSC; 161143c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com } 161243c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com if (dst) { 161343c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com *dst = rec.fDC; 161443c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com } 161543c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com return true; 161643c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com} 161743c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com 161830da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.combool SkXfermode::AsMode(const SkXfermode* xfer, Mode* mode) { 16198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == xfer) { 16208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mode) { 16218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *mode = kSrcOver_Mode; 16228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 16238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 16248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1625c0d4aa2088a0788f9df221497945d2ba1b342f44reed@google.com return xfer->asMode(mode); 16268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 162830da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.combool SkXfermode::IsMode(const SkXfermode* xfer, Mode mode) { 1629e303fcf68d6fee2bf9ee0c4f6fb330a2c3e41a01mike@reedtribe.org // if xfer==null then the mode is srcover 1630e303fcf68d6fee2bf9ee0c4f6fb330a2c3e41a01mike@reedtribe.org Mode m = kSrcOver_Mode; 1631e303fcf68d6fee2bf9ee0c4f6fb330a2c3e41a01mike@reedtribe.org if (xfer && !xfer->asMode(&m)) { 1632e303fcf68d6fee2bf9ee0c4f6fb330a2c3e41a01mike@reedtribe.org return false; 1633e303fcf68d6fee2bf9ee0c4f6fb330a2c3e41a01mike@reedtribe.org } 1634e303fcf68d6fee2bf9ee0c4f6fb330a2c3e41a01mike@reedtribe.org return mode == m; 1635e303fcf68d6fee2bf9ee0c4f6fb330a2c3e41a01mike@reedtribe.org} 1636e303fcf68d6fee2bf9ee0c4f6fb330a2c3e41a01mike@reedtribe.org 1637dcfb7cf336cafffd8d149c908b615e1deaa3a49begdanielbool SkXfermode::SupportsCoverageAsAlpha(const SkXfermode* xfer) { 1638dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel // if xfer is NULL we treat it as srcOver which always supports coverageAsAlpha 1639dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel if (!xfer) { 1640dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel return true; 1641dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel } 1642dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel 1643dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel return xfer->supportsCoverageAsAlpha(); 1644dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel} 1645dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel 1646dcfb7cf336cafffd8d149c908b615e1deaa3a49begdanielbool SkXfermode::IsOpaque(const SkXfermode* xfer, SrcColorOpacity opacityType) { 1647dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel // if xfer is NULL we treat it as srcOver which is opaque if our src is opaque 1648dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel if (!xfer) { 1649dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel return SkXfermode::kOpaque_SrcColorOpacity == opacityType; 1650dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel } 1651dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel 1652dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel return xfer->isOpaque(opacityType); 1653dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel} 1654dcfb7cf336cafffd8d149c908b615e1deaa3a49begdaniel 16558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 16568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////// 16bit xfermode procs 16578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG 16598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic bool require_255(SkPMColor src) { return SkGetPackedA32(src) == 0xFF; } 16608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic bool require_0(SkPMColor src) { return SkGetPackedA32(src) == 0; } 16618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 16628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic uint16_t src_modeproc16_255(SkPMColor src, uint16_t dst) { 16648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(require_255(src)); 16658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkPixel32ToPixel16(src); 16668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic uint16_t dst_modeproc16(SkPMColor src, uint16_t dst) { 16698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return dst; 16708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic uint16_t srcover_modeproc16_0(SkPMColor src, uint16_t dst) { 16738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(require_0(src)); 16748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return dst; 16758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic uint16_t srcover_modeproc16_255(SkPMColor src, uint16_t dst) { 16788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(require_255(src)); 16798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkPixel32ToPixel16(src); 16808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic uint16_t dstover_modeproc16_0(SkPMColor src, uint16_t dst) { 16838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(require_0(src)); 16848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return dst; 16858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic uint16_t dstover_modeproc16_255(SkPMColor src, uint16_t dst) { 16888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(require_255(src)); 16898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return dst; 16908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic uint16_t srcin_modeproc16_255(SkPMColor src, uint16_t dst) { 16938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(require_255(src)); 16948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkPixel32ToPixel16(src); 16958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic uint16_t dstin_modeproc16_255(SkPMColor src, uint16_t dst) { 16988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(require_255(src)); 16998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return dst; 17008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic uint16_t dstout_modeproc16_0(SkPMColor src, uint16_t dst) { 17038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(require_0(src)); 17048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return dst; 17058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic uint16_t srcatop_modeproc16(SkPMColor src, uint16_t dst) { 17088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned isa = 255 - SkGetPackedA32(src); 17091447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 17108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkPackRGB16( 17118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPacked32ToR16(src) + SkAlphaMulAlpha(SkGetPackedR16(dst), isa), 17128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPacked32ToG16(src) + SkAlphaMulAlpha(SkGetPackedG16(dst), isa), 17138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPacked32ToB16(src) + SkAlphaMulAlpha(SkGetPackedB16(dst), isa)); 17148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic uint16_t srcatop_modeproc16_0(SkPMColor src, uint16_t dst) { 17178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(require_0(src)); 17188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return dst; 17198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic uint16_t srcatop_modeproc16_255(SkPMColor src, uint16_t dst) { 17228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(require_255(src)); 17238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkPixel32ToPixel16(src); 17248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic uint16_t dstatop_modeproc16_255(SkPMColor src, uint16_t dst) { 17278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(require_255(src)); 17288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return dst; 17298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/********* 17328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com darken and lighten boil down to this. 17338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com darken = (1 - Sa) * Dc + min(Sc, Dc) 17358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com lighten = (1 - Sa) * Dc + max(Sc, Dc) 17368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (Sa == 0) these become 17388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com darken = Dc + min(0, Dc) = 0 17398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com lighten = Dc + max(0, Dc) = Dc 17408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (Sa == 1) these become 17428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com darken = min(Sc, Dc) 17438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com lighten = max(Sc, Dc) 17448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 17458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic uint16_t darken_modeproc16_0(SkPMColor src, uint16_t dst) { 17478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(require_0(src)); 17488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return 0; 17498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic uint16_t darken_modeproc16_255(SkPMColor src, uint16_t dst) { 17528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(require_255(src)); 17538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned r = SkFastMin32(SkPacked32ToR16(src), SkGetPackedR16(dst)); 17548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned g = SkFastMin32(SkPacked32ToG16(src), SkGetPackedG16(dst)); 17558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned b = SkFastMin32(SkPacked32ToB16(src), SkGetPackedB16(dst)); 17568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkPackRGB16(r, g, b); 17578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic uint16_t lighten_modeproc16_0(SkPMColor src, uint16_t dst) { 17608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(require_0(src)); 17618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return dst; 17628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic uint16_t lighten_modeproc16_255(SkPMColor src, uint16_t dst) { 17658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(require_255(src)); 17668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned r = SkMax32(SkPacked32ToR16(src), SkGetPackedR16(dst)); 17678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned g = SkMax32(SkPacked32ToG16(src), SkGetPackedG16(dst)); 17688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned b = SkMax32(SkPacked32ToB16(src), SkGetPackedB16(dst)); 17698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkPackRGB16(r, g, b); 17708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstruct Proc16Rec { 17738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkXfermodeProc16 fProc16_0; 17748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkXfermodeProc16 fProc16_255; 17758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkXfermodeProc16 fProc16_General; 17768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 17778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1778a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.comstatic const Proc16Rec gModeProcs16[] = { 17798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { NULL, NULL, NULL }, // CLEAR 17808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { NULL, src_modeproc16_255, NULL }, 17818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { dst_modeproc16, dst_modeproc16, dst_modeproc16 }, 17828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { srcover_modeproc16_0, srcover_modeproc16_255, NULL }, 17838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { dstover_modeproc16_0, dstover_modeproc16_255, NULL }, 17848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { NULL, srcin_modeproc16_255, NULL }, 17858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { NULL, dstin_modeproc16_255, NULL }, 17868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { NULL, NULL, NULL },// SRC_OUT 17878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { dstout_modeproc16_0, NULL, NULL }, 17888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { srcatop_modeproc16_0, srcatop_modeproc16_255, srcatop_modeproc16 }, 17898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { NULL, dstatop_modeproc16_255, NULL }, 17908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { NULL, NULL, NULL }, // XOR 1791a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com 1792a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com { NULL, NULL, NULL }, // plus 17938d3cd7a170c810e3816bf00220cbef51e7b16795reed@google.com { NULL, NULL, NULL }, // modulate 1794a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com { NULL, NULL, NULL }, // screen 1795a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com { NULL, NULL, NULL }, // overlay 1796a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com { darken_modeproc16_0, darken_modeproc16_255, NULL }, // darken 1797a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com { lighten_modeproc16_0, lighten_modeproc16_255, NULL }, // lighten 1798a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com { NULL, NULL, NULL }, // colordodge 1799a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com { NULL, NULL, NULL }, // colorburn 1800a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com { NULL, NULL, NULL }, // hardlight 1801a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com { NULL, NULL, NULL }, // softlight 1802a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com { NULL, NULL, NULL }, // difference 1803a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com { NULL, NULL, NULL }, // exclusion 1804b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org { NULL, NULL, NULL }, // multiply 1805b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org { NULL, NULL, NULL }, // hue 1806b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org { NULL, NULL, NULL }, // saturation 1807b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org { NULL, NULL, NULL }, // color 1808b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org { NULL, NULL, NULL }, // luminosity 18098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 18108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1811a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.comSkXfermodeProc16 SkXfermode::GetProc16(Mode mode, SkColor srcColor) { 18128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkXfermodeProc16 proc16 = NULL; 1813a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com if ((unsigned)mode < kModeCount) { 1814a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com const Proc16Rec& rec = gModeProcs16[mode]; 18158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned a = SkColorGetA(srcColor); 18168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (0 == a) { 18188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com proc16 = rec.fProc16_0; 18198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else if (255 == a) { 18208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com proc16 = rec.fProc16_255; 18218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 18228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com proc16 = rec.fProc16_General; 18238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return proc16; 18268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1828d26147adbbdca85f07dff432025afee0c8614387caryclark@google.comSK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode) 1829d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode) 1830d26147adbbdca85f07dff432025afee0c8614387caryclark@google.comSK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 1831