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 9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkXfermode.h" 11c524e98f1edf06b53e65543f5f28217fa13b7aa9commit-bot@chromium.org#include "SkXfermode_opts_SSE2.h" 12df187c7eb27d7616b75d91f3329deb97c4cd6de2commit-bot@chromium.org#include "SkXfermode_proccoeff.h" 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorPriv.h" 1497de357270e54be53acb17e1cb4b4d5e25bacc01commit-bot@chromium.org#include "SkLazyPtr.h" 154b163ed2c22facbe8891616874ae07ba7827d9c9reed@google.com#include "SkMathPriv.h" 16140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org#include "SkReadBuffer.h" 17b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com#include "SkString.h" 18cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org#include "SkUtilsArm.h" 19140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org#include "SkWriteBuffer.h" 20cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org 21cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org#if !SK_ARM_NEON_IS_NONE 22cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org#include "SkXfermode_opts_arm_neon.h" 23cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org#endif 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkAlphaMulAlpha(a, b) SkMulDiv255Round(a, b) 268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27fc25abdabff76f913fb9d4f373418c10a1eca92breed@android.com#if 0 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// idea for higher precision blends in xfer procs (and slightly faster) 298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// see DstATop as a probable caller 308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic U8CPU mulmuldiv255round(U8CPU a, U8CPU b, U8CPU c, U8CPU d) { 318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(a <= 255); 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(b <= 255); 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(c <= 255); 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(d <= 255); 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned prod = SkMulS16(a, b) + SkMulS16(c, d) + 128; 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned result = (prod + (prod >> 8)) >> 8; 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(result <= 255); 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return result; 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 40fc25abdabff76f913fb9d4f373418c10a1eca92breed@android.com#endif 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 42da94699149a40a90731425766d3b994e34c5ba26deanm@chromium.orgstatic inline unsigned saturated_add(unsigned a, unsigned b) { 43543ed9352c7dfd93071c08b14930cca2e82a08d4reed@android.com SkASSERT(a <= 255); 44543ed9352c7dfd93071c08b14930cca2e82a08d4reed@android.com SkASSERT(b <= 255); 45543ed9352c7dfd93071c08b14930cca2e82a08d4reed@android.com unsigned sum = a + b; 46543ed9352c7dfd93071c08b14930cca2e82a08d4reed@android.com if (sum > 255) { 47543ed9352c7dfd93071c08b14930cca2e82a08d4reed@android.com sum = 255; 48543ed9352c7dfd93071c08b14930cca2e82a08d4reed@android.com } 49543ed9352c7dfd93071c08b14930cca2e82a08d4reed@android.com return sum; 50543ed9352c7dfd93071c08b14930cca2e82a08d4reed@android.com} 51543ed9352c7dfd93071c08b14930cca2e82a08d4reed@android.com 52da94699149a40a90731425766d3b994e34c5ba26deanm@chromium.orgstatic inline int clamp_signed_byte(int n) { 53a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com if (n < 0) { 54a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com n = 0; 55a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com } else if (n > 255) { 56a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com n = 255; 57a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com } 58a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com return n; 59a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com} 60a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com 61da94699149a40a90731425766d3b994e34c5ba26deanm@chromium.orgstatic inline int clamp_div255round(int prod) { 62a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com if (prod <= 0) { 63a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com return 0; 64a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com } else if (prod >= 255*255) { 65a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com return 255; 66a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com } else { 67a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com return SkDiv255Round(prod); 68a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com } 69a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com} 70a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com 718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org// kClear_Mode, //!< [0, 0] 7448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic SkPMColor clear_modeproc(SkPMColor src, SkPMColor dst) { 7548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return 0; 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org// kSrc_Mode, //!< [Sa, Sc] 7948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic SkPMColor src_modeproc(SkPMColor src, SkPMColor dst) { 8048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return src; 818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org// kDst_Mode, //!< [Da, Dc] 8448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic SkPMColor dst_modeproc(SkPMColor src, SkPMColor dst) { 8548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return dst; 8648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 881447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com// kSrcOver_Mode, //!< [Sa + Da - Sa*Da, Sc + (1 - Sa)*Dc] 8948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic SkPMColor srcover_modeproc(SkPMColor src, SkPMColor dst) { 9048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org#if 0 9148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org // this is the old, more-correct way, but it doesn't guarantee that dst==255 9248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org // will always stay opaque 9348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return src + SkAlphaMulQ(dst, SkAlpha255To256(255 - SkGetPackedA32(src))); 9448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org#else 9548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org // this is slightly faster, but more importantly guarantees that dst==255 9648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org // will always stay opaque 9748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return src + SkAlphaMulQ(dst, 256 - SkGetPackedA32(src)); 9848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org#endif 998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org// kDstOver_Mode, //!< [Sa + Da - Sa*Da, Dc + (1 - Da)*Sc] 10248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic SkPMColor dstover_modeproc(SkPMColor src, SkPMColor dst) { 10348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org // this is the reverse of srcover, just flipping src and dst 10448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org // see srcover's comment about the 256 for opaqueness guarantees 10548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return dst + SkAlphaMulQ(src, 256 - SkGetPackedA32(dst)); 10648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org// kSrcIn_Mode, //!< [Sa * Da, Sc * Da] 10948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic SkPMColor srcin_modeproc(SkPMColor src, SkPMColor dst) { 11048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return SkAlphaMulQ(src, SkAlpha255To256(SkGetPackedA32(dst))); 1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org// kDstIn_Mode, //!< [Sa * Da, Sa * Dc] 11448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic SkPMColor dstin_modeproc(SkPMColor src, SkPMColor dst) { 11548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return SkAlphaMulQ(dst, SkAlpha255To256(SkGetPackedA32(src))); 1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org// kSrcOut_Mode, //!< [Sa * (1 - Da), Sc * (1 - Da)] 11948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic SkPMColor srcout_modeproc(SkPMColor src, SkPMColor dst) { 12048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return SkAlphaMulQ(src, SkAlpha255To256(255 - SkGetPackedA32(dst))); 12148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org// kDstOut_Mode, //!< [Da * (1 - Sa), Dc * (1 - Sa)] 12448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic SkPMColor dstout_modeproc(SkPMColor src, SkPMColor dst) { 12548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return SkAlphaMulQ(dst, SkAlpha255To256(255 - SkGetPackedA32(src))); 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org// kSrcATop_Mode, //!< [Da, Sc * Da + (1 - Sa) * Dc] 12948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic SkPMColor srcatop_modeproc(SkPMColor src, SkPMColor dst) { 13048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org unsigned sa = SkGetPackedA32(src); 13148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org unsigned da = SkGetPackedA32(dst); 13248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org unsigned isa = 255 - sa; 1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return SkPackARGB32(da, 13548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkAlphaMulAlpha(da, SkGetPackedR32(src)) + 13648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkAlphaMulAlpha(isa, SkGetPackedR32(dst)), 13748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkAlphaMulAlpha(da, SkGetPackedG32(src)) + 13848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkAlphaMulAlpha(isa, SkGetPackedG32(dst)), 13948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkAlphaMulAlpha(da, SkGetPackedB32(src)) + 14048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkAlphaMulAlpha(isa, SkGetPackedB32(dst))); 14148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org// kDstATop_Mode, //!< [Sa, Sa * Dc + Sc * (1 - Da)] 14448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic SkPMColor dstatop_modeproc(SkPMColor src, SkPMColor dst) { 14548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org unsigned sa = SkGetPackedA32(src); 14648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org unsigned da = SkGetPackedA32(dst); 14748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org unsigned ida = 255 - da; 1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return SkPackARGB32(sa, 15048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkAlphaMulAlpha(ida, SkGetPackedR32(src)) + 15148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkAlphaMulAlpha(sa, SkGetPackedR32(dst)), 15248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkAlphaMulAlpha(ida, SkGetPackedG32(src)) + 15348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkAlphaMulAlpha(sa, SkGetPackedG32(dst)), 15448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkAlphaMulAlpha(ida, SkGetPackedB32(src)) + 15548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkAlphaMulAlpha(sa, SkGetPackedB32(dst))); 1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 15848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org// kXor_Mode [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc] 15948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic SkPMColor xor_modeproc(SkPMColor src, SkPMColor dst) { 16048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org unsigned sa = SkGetPackedA32(src); 16148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org unsigned da = SkGetPackedA32(dst); 16248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org unsigned isa = 255 - sa; 16348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org unsigned ida = 255 - da; 1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return SkPackARGB32(sa + da - (SkAlphaMulAlpha(sa, da) << 1), 16648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkAlphaMulAlpha(ida, SkGetPackedR32(src)) + 16748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkAlphaMulAlpha(isa, SkGetPackedR32(dst)), 16848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkAlphaMulAlpha(ida, SkGetPackedG32(src)) + 16948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkAlphaMulAlpha(isa, SkGetPackedG32(dst)), 17048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkAlphaMulAlpha(ida, SkGetPackedB32(src)) + 17148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkAlphaMulAlpha(isa, SkGetPackedB32(dst))); 17248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org/////////////////////////////////////////////////////////////////////////////// 17548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 17648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org// kPlus_Mode 17748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic SkPMColor plus_modeproc(SkPMColor src, SkPMColor dst) { 17848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org unsigned b = saturated_add(SkGetPackedB32(src), SkGetPackedB32(dst)); 17948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org unsigned g = saturated_add(SkGetPackedG32(src), SkGetPackedG32(dst)); 18048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org unsigned r = saturated_add(SkGetPackedR32(src), SkGetPackedR32(dst)); 18148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org unsigned a = saturated_add(SkGetPackedA32(src), SkGetPackedA32(dst)); 18248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return SkPackARGB32(a, r, g, b); 1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1858d3cd7a170c810e3816bf00220cbef51e7b16795reed@google.com// kModulate_Mode 1868d3cd7a170c810e3816bf00220cbef51e7b16795reed@google.comstatic SkPMColor modulate_modeproc(SkPMColor src, SkPMColor dst) { 18748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int a = SkAlphaMulAlpha(SkGetPackedA32(src), SkGetPackedA32(dst)); 18848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int r = SkAlphaMulAlpha(SkGetPackedR32(src), SkGetPackedR32(dst)); 18948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int g = SkAlphaMulAlpha(SkGetPackedG32(src), SkGetPackedG32(dst)); 19048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int b = SkAlphaMulAlpha(SkGetPackedB32(src), SkGetPackedB32(dst)); 19148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return SkPackARGB32(a, r, g, b); 19248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 194a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.comstatic inline int srcover_byte(int a, int b) { 195a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com return a + b - SkAlphaMulAlpha(a, b); 196a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com} 19725cfa693420b6da4182bda42ba15970999b840ddreed@google.com 19825cfa693420b6da4182bda42ba15970999b840ddreed@google.com// kMultiply_Mode 19925cfa693420b6da4182bda42ba15970999b840ddreed@google.com// B(Cb, Cs) = Cb x Cs 20025cfa693420b6da4182bda42ba15970999b840ddreed@google.com// multiply uses its own version of blendfunc_byte because sa and da are not needed 20125cfa693420b6da4182bda42ba15970999b840ddreed@google.comstatic int blendfunc_multiply_byte(int sc, int dc, int sa, int da) { 20225cfa693420b6da4182bda42ba15970999b840ddreed@google.com return clamp_div255round(sc * (255 - da) + dc * (255 - sa) + sc * dc); 20325cfa693420b6da4182bda42ba15970999b840ddreed@google.com} 20425cfa693420b6da4182bda42ba15970999b840ddreed@google.com 20525cfa693420b6da4182bda42ba15970999b840ddreed@google.comstatic SkPMColor multiply_modeproc(SkPMColor src, SkPMColor dst) { 20625cfa693420b6da4182bda42ba15970999b840ddreed@google.com int sa = SkGetPackedA32(src); 20725cfa693420b6da4182bda42ba15970999b840ddreed@google.com int da = SkGetPackedA32(dst); 20825cfa693420b6da4182bda42ba15970999b840ddreed@google.com int a = srcover_byte(sa, da); 20925cfa693420b6da4182bda42ba15970999b840ddreed@google.com int r = blendfunc_multiply_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 21025cfa693420b6da4182bda42ba15970999b840ddreed@google.com int g = blendfunc_multiply_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 21125cfa693420b6da4182bda42ba15970999b840ddreed@google.com int b = blendfunc_multiply_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 21225cfa693420b6da4182bda42ba15970999b840ddreed@google.com return SkPackARGB32(a, r, g, b); 21325cfa693420b6da4182bda42ba15970999b840ddreed@google.com} 21425cfa693420b6da4182bda42ba15970999b840ddreed@google.com 21525cfa693420b6da4182bda42ba15970999b840ddreed@google.com// kScreen_Mode 216a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.comstatic SkPMColor screen_modeproc(SkPMColor src, SkPMColor dst) { 217a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int a = srcover_byte(SkGetPackedA32(src), SkGetPackedA32(dst)); 218a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int r = srcover_byte(SkGetPackedR32(src), SkGetPackedR32(dst)); 219a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int g = srcover_byte(SkGetPackedG32(src), SkGetPackedG32(dst)); 220a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int b = srcover_byte(SkGetPackedB32(src), SkGetPackedB32(dst)); 221a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com return SkPackARGB32(a, r, g, b); 222a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com} 223a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com 224a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com// kOverlay_Mode 225a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.comstatic inline int overlay_byte(int sc, int dc, int sa, int da) { 226a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int tmp = sc * (255 - da) + dc * (255 - sa); 227a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int rc; 228a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com if (2 * dc <= da) { 229a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com rc = 2 * sc * dc; 230a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com } else { 231a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com rc = sa * da - 2 * (da - dc) * (sa - sc); 232a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com } 233a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com return clamp_div255round(rc + tmp); 234a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com} 235a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.comstatic SkPMColor overlay_modeproc(SkPMColor src, SkPMColor dst) { 236a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int sa = SkGetPackedA32(src); 237a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int da = SkGetPackedA32(dst); 238a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int a = srcover_byte(sa, da); 239a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int r = overlay_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 240a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int g = overlay_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 241a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int b = overlay_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 242a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com return SkPackARGB32(a, r, g, b); 243a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com} 244a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com 245a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com// kDarken_Mode 246a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.comstatic inline int darken_byte(int sc, int dc, int sa, int da) { 247a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int sd = sc * da; 248a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int ds = dc * sa; 249a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com if (sd < ds) { 250a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com // srcover 251a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com return sc + dc - SkDiv255Round(ds); 252a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com } else { 253a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com // dstover 254a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com return dc + sc - SkDiv255Round(sd); 255a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com } 256a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com} 2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkPMColor darken_modeproc(SkPMColor src, SkPMColor dst) { 258a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int sa = SkGetPackedA32(src); 259a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int da = SkGetPackedA32(dst); 260a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int a = srcover_byte(sa, da); 261a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int r = darken_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 262a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int g = darken_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 263a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int b = darken_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 264a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com return SkPackARGB32(a, r, g, b); 265a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com} 2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 267a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com// kLighten_Mode 268a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.comstatic inline int lighten_byte(int sc, int dc, int sa, int da) { 269a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int sd = sc * da; 270a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int ds = dc * sa; 271a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com if (sd > ds) { 272a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com // srcover 273a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com return sc + dc - SkDiv255Round(ds); 274a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com } else { 275a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com // dstover 276a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com return dc + sc - SkDiv255Round(sd); 277a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com } 278a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com} 279a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.comstatic SkPMColor lighten_modeproc(SkPMColor src, SkPMColor dst) { 280a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int sa = SkGetPackedA32(src); 281a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int da = SkGetPackedA32(dst); 282a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int a = srcover_byte(sa, da); 283a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int r = lighten_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 284a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int g = lighten_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 285a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int b = lighten_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 286a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com return SkPackARGB32(a, r, g, b); 287a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com} 2888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 289a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com// kColorDodge_Mode 290a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.comstatic inline int colordodge_byte(int sc, int dc, int sa, int da) { 291a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int diff = sa - sc; 292a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com int rc; 293311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org if (0 == dc) { 294311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org return SkAlphaMulAlpha(sc, 255 - da); 295311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org } else if (0 == diff) { 296a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com rc = sa * da + sc * (255 - da) + dc * (255 - sa); 297a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com } else { 298311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org diff = dc * sa / diff; 299311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org rc = sa * ((da < diff) ? da : diff) + sc * (255 - da) + dc * (255 - sa); 300a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com } 301311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org return clamp_div255round(rc); 30248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 30348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic SkPMColor colordodge_modeproc(SkPMColor src, SkPMColor dst) { 30448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int sa = SkGetPackedA32(src); 30548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int da = SkGetPackedA32(dst); 30648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int a = srcover_byte(sa, da); 30748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int r = colordodge_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 30848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int g = colordodge_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 30948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int b = colordodge_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 31048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return SkPackARGB32(a, r, g, b); 31148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 31248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 31348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org// kColorBurn_Mode 31448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic inline int colorburn_byte(int sc, int dc, int sa, int da) { 31548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int rc; 316311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org if (dc == da) { 317311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org rc = sa * da + sc * (255 - da) + dc * (255 - sa); 31848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } else if (0 == sc) { 31948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return SkAlphaMulAlpha(dc, 255 - sa); 32048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } else { 321311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org int tmp = (da - dc) * sa / sc; 322311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org rc = sa * (da - ((da < tmp) ? da : tmp)) 323311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org + sc * (255 - da) + dc * (255 - sa); 32448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } 325311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org return clamp_div255round(rc); 32648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 32748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic SkPMColor colorburn_modeproc(SkPMColor src, SkPMColor dst) { 32848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int sa = SkGetPackedA32(src); 32948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int da = SkGetPackedA32(dst); 33048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int a = srcover_byte(sa, da); 33148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int r = colorburn_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 33248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int g = colorburn_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 33348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int b = colorburn_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 33448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return SkPackARGB32(a, r, g, b); 33548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 33648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 33748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org// kHardLight_Mode 33848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic inline int hardlight_byte(int sc, int dc, int sa, int da) { 33948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int rc; 34048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org if (2 * sc <= sa) { 34148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org rc = 2 * sc * dc; 34248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } else { 34348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org rc = sa * da - 2 * (da - dc) * (sa - sc); 34448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } 34548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return clamp_div255round(rc + sc * (255 - da) + dc * (255 - sa)); 34648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 34748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic SkPMColor hardlight_modeproc(SkPMColor src, SkPMColor dst) { 34848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int sa = SkGetPackedA32(src); 34948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int da = SkGetPackedA32(dst); 35048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int a = srcover_byte(sa, da); 35148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int r = hardlight_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 35248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int g = hardlight_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 35348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int b = hardlight_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 35448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return SkPackARGB32(a, r, g, b); 35548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 35648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 35748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org// returns 255 * sqrt(n/255) 35848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic U8CPU sqrt_unit_byte(U8CPU n) { 35948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return SkSqrtBits(n, 15+4); 36048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 36148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 36248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org// kSoftLight_Mode 36348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic inline int softlight_byte(int sc, int dc, int sa, int da) { 36448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int m = da ? dc * 256 / da : 0; 36548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int rc; 36648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org if (2 * sc <= sa) { 36748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org rc = dc * (sa + ((2 * sc - sa) * (256 - m) >> 8)); 36848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } else if (4 * dc <= da) { 36948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int tmp = (4 * m * (4 * m + 256) * (m - 256) >> 16) + 7 * m; 37048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org rc = dc * sa + (da * (2 * sc - sa) * tmp >> 8); 37148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } else { 37248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int tmp = sqrt_unit_byte(m) - m; 37348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org rc = dc * sa + (da * (2 * sc - sa) * tmp >> 8); 37448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } 37548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return clamp_div255round(rc + sc * (255 - da) + dc * (255 - sa)); 37648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 37748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic SkPMColor softlight_modeproc(SkPMColor src, SkPMColor dst) { 37848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int sa = SkGetPackedA32(src); 37948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int da = SkGetPackedA32(dst); 38048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int a = srcover_byte(sa, da); 38148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int r = softlight_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 38248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int g = softlight_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 38348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int b = softlight_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 38448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return SkPackARGB32(a, r, g, b); 38548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 38648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 38748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org// kDifference_Mode 38848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic inline int difference_byte(int sc, int dc, int sa, int da) { 38948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int tmp = SkMin32(sc * da, dc * sa); 39048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return clamp_signed_byte(sc + dc - 2 * SkDiv255Round(tmp)); 39148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 39248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic SkPMColor difference_modeproc(SkPMColor src, SkPMColor dst) { 39348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int sa = SkGetPackedA32(src); 39448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int da = SkGetPackedA32(dst); 39548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int a = srcover_byte(sa, da); 39648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int r = difference_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 39748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int g = difference_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 39848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int b = difference_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 39948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return SkPackARGB32(a, r, g, b); 40048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 40148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 40248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org// kExclusion_Mode 403e38e53b5327e2618a97fb26a697a477b74c44d3dcommit-bot@chromium.orgstatic inline int exclusion_byte(int sc, int dc, int, int) { 40448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org // this equations is wacky, wait for SVG to confirm it 405e38e53b5327e2618a97fb26a697a477b74c44d3dcommit-bot@chromium.org //int r = sc * da + dc * sa - 2 * sc * dc + sc * (255 - da) + dc * (255 - sa); 406e38e53b5327e2618a97fb26a697a477b74c44d3dcommit-bot@chromium.org 407e38e53b5327e2618a97fb26a697a477b74c44d3dcommit-bot@chromium.org // The above equation can be simplified as follows 408e38e53b5327e2618a97fb26a697a477b74c44d3dcommit-bot@chromium.org int r = 255*(sc + dc) - 2 * sc * dc; 40948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return clamp_div255round(r); 41048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 41148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.orgstatic SkPMColor exclusion_modeproc(SkPMColor src, SkPMColor dst) { 41248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int sa = SkGetPackedA32(src); 41348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int da = SkGetPackedA32(dst); 41448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int a = srcover_byte(sa, da); 41548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int r = exclusion_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 41648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int g = exclusion_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 41748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org int b = exclusion_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 41848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return SkPackARGB32(a, r, g, b); 41948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 42048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 421b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org// The CSS compositing spec introduces the following formulas: 422b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org// (See https://dvcs.w3.org/hg/FXTF/rawfile/tip/compositing/index.html#blendingnonseparable) 423b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org// SkComputeLuminance is similar to this formula but it uses the new definition from Rec. 709 424b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org// while PDF and CG uses the one from Rec. Rec. 601 425b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org// See http://www.glennchan.info/articles/technical/hd-versus-sd-color-space/hd-versus-sd-color-space.htm 426b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.orgstatic inline int Lum(int r, int g, int b) 427b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org{ 428311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org return SkDiv255Round(r * 77 + g * 150 + b * 28); 429b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org} 430b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 431b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.orgstatic inline int min2(int a, int b) { return a < b ? a : b; } 432b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.orgstatic inline int max2(int a, int b) { return a > b ? a : b; } 43364334352cc3f29f52dfa07225d65eb218d2fd830skia.committer@gmail.com#define minimum(a, b, c) min2(min2(a, b), c) 43464334352cc3f29f52dfa07225d65eb218d2fd830skia.committer@gmail.com#define maximum(a, b, c) max2(max2(a, b), c) 435b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 436b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.orgstatic inline int Sat(int r, int g, int b) { 437b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org return maximum(r, g, b) - minimum(r, g, b); 438b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org} 439b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 440b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.orgstatic inline void setSaturationComponents(int* Cmin, int* Cmid, int* Cmax, int s) { 4413c1ea3a7e5127513d3b3335d92292e02f273efefreed@google.com if(*Cmax > *Cmin) { 442311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org *Cmid = SkMulDiv(*Cmid - *Cmin, s, *Cmax - *Cmin); 443b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org *Cmax = s; 444b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org } else { 445b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org *Cmax = 0; 446b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org *Cmid = 0; 447b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org } 448b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 449b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org *Cmin = 0; 450b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org} 451b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 452b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.orgstatic inline void SetSat(int* r, int* g, int* b, int s) { 453b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org if(*r <= *g) { 454b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org if(*g <= *b) { 455b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org setSaturationComponents(r, g, b, s); 456b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org } else if(*r <= *b) { 457b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org setSaturationComponents(r, b, g, s); 458b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org } else { 459b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org setSaturationComponents(b, r, g, s); 460b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org } 461b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org } else if(*r <= *b) { 462b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org setSaturationComponents(g, r, b, s); 463b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org } else if(*g <= *b) { 464b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org setSaturationComponents(g, b, r, s); 465b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org } else { 466b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org setSaturationComponents(b, g, r, s); 467b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org } 468b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org} 469b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 470311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.orgstatic inline void clipColor(int* r, int* g, int* b, int a) { 471b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int L = Lum(*r, *g, *b); 472b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int n = minimum(*r, *g, *b); 473b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int x = maximum(*r, *g, *b); 474b85ebea5267ec0b9630d828840fa2d7df29b9f43commit-bot@chromium.org int denom; 475b85ebea5267ec0b9630d828840fa2d7df29b9f43commit-bot@chromium.org if ((n < 0) && (denom = L - n)) { // Compute denom and make sure it's non zero 476b85ebea5267ec0b9630d828840fa2d7df29b9f43commit-bot@chromium.org *r = L + SkMulDiv(*r - L, L, denom); 477b85ebea5267ec0b9630d828840fa2d7df29b9f43commit-bot@chromium.org *g = L + SkMulDiv(*g - L, L, denom); 478b85ebea5267ec0b9630d828840fa2d7df29b9f43commit-bot@chromium.org *b = L + SkMulDiv(*b - L, L, denom); 479b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org } 480b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 481b85ebea5267ec0b9630d828840fa2d7df29b9f43commit-bot@chromium.org if ((x > a) && (denom = x - L)) { // Compute denom and make sure it's non zero 482b85ebea5267ec0b9630d828840fa2d7df29b9f43commit-bot@chromium.org int numer = a - L; 483b85ebea5267ec0b9630d828840fa2d7df29b9f43commit-bot@chromium.org *r = L + SkMulDiv(*r - L, numer, denom); 484b85ebea5267ec0b9630d828840fa2d7df29b9f43commit-bot@chromium.org *g = L + SkMulDiv(*g - L, numer, denom); 485b85ebea5267ec0b9630d828840fa2d7df29b9f43commit-bot@chromium.org *b = L + SkMulDiv(*b - L, numer, denom); 486b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org } 487b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org} 488b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 489311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.orgstatic inline void SetLum(int* r, int* g, int* b, int a, int l) { 490b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int d = l - Lum(*r, *g, *b); 491b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org *r += d; 492b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org *g += d; 493b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org *b += d; 494b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 495311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org clipColor(r, g, b, a); 496b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org} 497b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 498b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org// non-separable blend modes are done in non-premultiplied alpha 499b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org#define blendfunc_nonsep_byte(sc, dc, sa, da, blendval) \ 500311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org clamp_div255round(sc * (255 - da) + dc * (255 - sa) + blendval) 501b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 502b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org// kHue_Mode 503b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org// B(Cb, Cs) = SetLum(SetSat(Cs, Sat(Cb)), Lum(Cb)) 504b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org// Create a color with the hue of the source color and the saturation and luminosity of the backdrop color. 505b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.orgstatic SkPMColor hue_modeproc(SkPMColor src, SkPMColor dst) { 506b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int sr = SkGetPackedR32(src); 507b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int sg = SkGetPackedG32(src); 508b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int sb = SkGetPackedB32(src); 509b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int sa = SkGetPackedA32(src); 510b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 511b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int dr = SkGetPackedR32(dst); 512b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int dg = SkGetPackedG32(dst); 513b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int db = SkGetPackedB32(dst); 514b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int da = SkGetPackedA32(dst); 515b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int Sr, Sg, Sb; 516b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 517b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org if(sa && da) { 518311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org Sr = sr * sa; 519311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org Sg = sg * sa; 520311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org Sb = sb * sa; 521311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org SetSat(&Sr, &Sg, &Sb, Sat(dr, dg, db) * sa); 522311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org SetLum(&Sr, &Sg, &Sb, sa * da, Lum(dr, dg, db) * sa); 523b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org } else { 524b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org Sr = 0; 525b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org Sg = 0; 526b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org Sb = 0; 527b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org } 528b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 529b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int a = srcover_byte(sa, da); 530b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int r = blendfunc_nonsep_byte(sr, dr, sa, da, Sr); 531b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int g = blendfunc_nonsep_byte(sg, dg, sa, da, Sg); 532b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int b = blendfunc_nonsep_byte(sb, db, sa, da, Sb); 533b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org return SkPackARGB32(a, r, g, b); 534b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org} 535b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 536b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org// kSaturation_Mode 537b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org// B(Cb, Cs) = SetLum(SetSat(Cb, Sat(Cs)), Lum(Cb)) 53864334352cc3f29f52dfa07225d65eb218d2fd830skia.committer@gmail.com// Create a color with the saturation of the source color and the hue and luminosity of the backdrop color. 539b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.orgstatic SkPMColor saturation_modeproc(SkPMColor src, SkPMColor dst) { 540b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int sr = SkGetPackedR32(src); 541b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int sg = SkGetPackedG32(src); 542b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int sb = SkGetPackedB32(src); 543b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int sa = SkGetPackedA32(src); 544b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 545b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int dr = SkGetPackedR32(dst); 546b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int dg = SkGetPackedG32(dst); 547b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int db = SkGetPackedB32(dst); 548b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int da = SkGetPackedA32(dst); 549b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int Dr, Dg, Db; 550b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 551b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org if(sa && da) { 552311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org Dr = dr * sa; 553311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org Dg = dg * sa; 554311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org Db = db * sa; 555311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org SetSat(&Dr, &Dg, &Db, Sat(sr, sg, sb) * da); 556311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org SetLum(&Dr, &Dg, &Db, sa * da, Lum(dr, dg, db) * sa); 557b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org } else { 558b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org Dr = 0; 559b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org Dg = 0; 560b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org Db = 0; 561b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org } 562b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 563b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int a = srcover_byte(sa, da); 564b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int r = blendfunc_nonsep_byte(sr, dr, sa, da, Dr); 565b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int g = blendfunc_nonsep_byte(sg, dg, sa, da, Dg); 566b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int b = blendfunc_nonsep_byte(sb, db, sa, da, Db); 567b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org return SkPackARGB32(a, r, g, b); 568b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org} 569b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 570b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org// kColor_Mode 571b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org// B(Cb, Cs) = SetLum(Cs, Lum(Cb)) 57264334352cc3f29f52dfa07225d65eb218d2fd830skia.committer@gmail.com// Create a color with the hue and saturation of the source color and the luminosity of the backdrop color. 573b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.orgstatic SkPMColor color_modeproc(SkPMColor src, SkPMColor dst) { 574b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int sr = SkGetPackedR32(src); 575b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int sg = SkGetPackedG32(src); 576b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int sb = SkGetPackedB32(src); 577b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int sa = SkGetPackedA32(src); 578b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 579b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int dr = SkGetPackedR32(dst); 580b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int dg = SkGetPackedG32(dst); 581b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int db = SkGetPackedB32(dst); 582b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int da = SkGetPackedA32(dst); 583b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int Sr, Sg, Sb; 584b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 585b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org if(sa && da) { 586311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org Sr = sr * da; 587311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org Sg = sg * da; 588311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org Sb = sb * da; 589311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org SetLum(&Sr, &Sg, &Sb, sa * da, Lum(dr, dg, db) * sa); 590b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org } else { 591b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org Sr = 0; 592b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org Sg = 0; 593b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org Sb = 0; 594b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org } 595b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 596b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int a = srcover_byte(sa, da); 597b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int r = blendfunc_nonsep_byte(sr, dr, sa, da, Sr); 598b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int g = blendfunc_nonsep_byte(sg, dg, sa, da, Sg); 599b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int b = blendfunc_nonsep_byte(sb, db, sa, da, Sb); 600b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org return SkPackARGB32(a, r, g, b); 601b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org} 602b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 603b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org// kLuminosity_Mode 604b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org// B(Cb, Cs) = SetLum(Cb, Lum(Cs)) 60564334352cc3f29f52dfa07225d65eb218d2fd830skia.committer@gmail.com// Create a color with the luminosity of the source color and the hue and saturation of the backdrop color. 606b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.orgstatic SkPMColor luminosity_modeproc(SkPMColor src, SkPMColor dst) { 607b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int sr = SkGetPackedR32(src); 608b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int sg = SkGetPackedG32(src); 609b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int sb = SkGetPackedB32(src); 610b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int sa = SkGetPackedA32(src); 611b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 612b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int dr = SkGetPackedR32(dst); 613b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int dg = SkGetPackedG32(dst); 614b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int db = SkGetPackedB32(dst); 615b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int da = SkGetPackedA32(dst); 616b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int Dr, Dg, Db; 617b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 618b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org if(sa && da) { 619311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org Dr = dr * sa; 620311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org Dg = dg * sa; 621311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org Db = db * sa; 622311d4eafab513adae3ef6c37dd4d573844bccd63commit-bot@chromium.org SetLum(&Dr, &Dg, &Db, sa * da, Lum(sr, sg, sb) * da); 623b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org } else { 624b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org Dr = 0; 625b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org Dg = 0; 626b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org Db = 0; 627b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org } 628b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 629b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int a = srcover_byte(sa, da); 630b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int r = blendfunc_nonsep_byte(sr, dr, sa, da, Dr); 631b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int g = blendfunc_nonsep_byte(sg, dg, sa, da, Dg); 632b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org int b = blendfunc_nonsep_byte(sb, db, sa, da, Db); 633b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org return SkPackARGB32(a, r, g, b); 634b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org} 635b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org 636df187c7eb27d7616b75d91f3329deb97c4cd6de2commit-bot@chromium.orgconst ProcCoeff gProcCoeffs[] = { 63748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org { clear_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kZero_Coeff }, 63848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org { src_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kZero_Coeff }, 63948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org { dst_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kOne_Coeff }, 64048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org { srcover_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kISA_Coeff }, 64148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org { dstover_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kOne_Coeff }, 64248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org { srcin_modeproc, SkXfermode::kDA_Coeff, SkXfermode::kZero_Coeff }, 64348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org { dstin_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kSA_Coeff }, 64448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org { srcout_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kZero_Coeff }, 64548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org { dstout_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kISA_Coeff }, 64648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org { srcatop_modeproc, SkXfermode::kDA_Coeff, SkXfermode::kISA_Coeff }, 64748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org { dstatop_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kSA_Coeff }, 64848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org { xor_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kISA_Coeff }, 64948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 650521e34e2912d835ab1b33a06cb8fb416510d7c53reed@google.com { plus_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kOne_Coeff }, 6518d3cd7a170c810e3816bf00220cbef51e7b16795reed@google.com { modulate_modeproc,SkXfermode::kZero_Coeff, SkXfermode::kSC_Coeff }, 652b0091b8382970c28dba57adc170e27b2e3d7394absalomon@google.com { screen_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kISC_Coeff }, 65348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org { overlay_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 65448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org { darken_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 65548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org { lighten_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 65648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org { colordodge_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 65748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org { colorburn_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 65848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org { hardlight_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 65948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org { softlight_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 66048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org { difference_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 66148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org { exclusion_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 66225cfa693420b6da4182bda42ba15970999b840ddreed@google.com { multiply_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 663b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org { hue_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 664b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org { saturation_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 665b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org { color_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 666b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org { luminosity_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 66748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org}; 66848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 66948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org/////////////////////////////////////////////////////////////////////////////// 67048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 67130da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.combool SkXfermode::asCoeff(Coeff* src, Coeff* dst) const { 67248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return false; 67348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 67448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 67530da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.combool SkXfermode::asMode(Mode* mode) const { 676c0d4aa2088a0788f9df221497945d2ba1b342f44reed@google.com return false; 67748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 67848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 679b0a8a377f832c59cee939ad721e1f87d378b7142joshualittbool SkXfermode::asFragmentProcessor(GrFragmentProcessor**, GrTexture*) const { 6801a6382f5e76c051ffbbb60f3a68524dfe57cf798senorblanco@chromium.org return false; 681f51c01328dc52a87c07e056d6fc4eb7452ccac7absalomon@google.com} 682f51c01328dc52a87c07e056d6fc4eb7452ccac7absalomon@google.com 683b0a8a377f832c59cee939ad721e1f87d378b7142joshualittbool SkXfermode::asFragmentProcessorOrCoeff(SkXfermode* xfermode, GrFragmentProcessor** fp, 684b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt Coeff* src, Coeff* dst, GrTexture* background) { 685f51c01328dc52a87c07e056d6fc4eb7452ccac7absalomon@google.com if (NULL == xfermode) { 686f51c01328dc52a87c07e056d6fc4eb7452ccac7absalomon@google.com return ModeAsCoeff(kSrcOver_Mode, src, dst); 6871a6382f5e76c051ffbbb60f3a68524dfe57cf798senorblanco@chromium.org } else if (xfermode->asCoeff(src, dst)) { 6881a6382f5e76c051ffbbb60f3a68524dfe57cf798senorblanco@chromium.org return true; 689f51c01328dc52a87c07e056d6fc4eb7452ccac7absalomon@google.com } else { 690b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt return xfermode->asFragmentProcessor(fp, background); 691f51c01328dc52a87c07e056d6fc4eb7452ccac7absalomon@google.com } 692f51c01328dc52a87c07e056d6fc4eb7452ccac7absalomon@google.com} 693f51c01328dc52a87c07e056d6fc4eb7452ccac7absalomon@google.com 69430da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.comSkPMColor SkXfermode::xferColor(SkPMColor src, SkPMColor dst) const{ 69548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org // no-op. subclasses should override this 69648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return dst; 69748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 69848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 699a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.comvoid SkXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 700a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com const SkPMColor* SK_RESTRICT src, int count, 70130da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.com const SkAlpha* SK_RESTRICT aa) const { 70248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkASSERT(dst && src && count >= 0); 70348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 70448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org if (NULL == aa) { 70548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org for (int i = count - 1; i >= 0; --i) { 70648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org dst[i] = this->xferColor(src[i], dst[i]); 70748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } 70848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } else { 70948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org for (int i = count - 1; i >= 0; --i) { 71048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org unsigned a = aa[i]; 71148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org if (0 != a) { 71248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkPMColor dstC = dst[i]; 71348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkPMColor C = this->xferColor(src[i], dstC); 71448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org if (0xFF != a) { 71548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org C = SkFourByteInterp(C, dstC, a); 71648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } 71748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org dst[i] = C; 71848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } 71948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } 72048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } 72148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 72248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 723a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.comvoid SkXfermode::xfer16(uint16_t* dst, 724a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com const SkPMColor* SK_RESTRICT src, int count, 72530da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.com const SkAlpha* SK_RESTRICT aa) const { 72648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkASSERT(dst && src && count >= 0); 72748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 72848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org if (NULL == aa) { 72948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org for (int i = count - 1; i >= 0; --i) { 73048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkPMColor dstC = SkPixel16ToPixel32(dst[i]); 73148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org dst[i] = SkPixel32ToPixel16_ToU16(this->xferColor(src[i], dstC)); 73248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } 73348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } else { 73448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org for (int i = count - 1; i >= 0; --i) { 73548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org unsigned a = aa[i]; 73648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org if (0 != a) { 73748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkPMColor dstC = SkPixel16ToPixel32(dst[i]); 73848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkPMColor C = this->xferColor(src[i], dstC); 73948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org if (0xFF != a) { 74048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org C = SkFourByteInterp(C, dstC, a); 74148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } 74248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org dst[i] = SkPixel32ToPixel16_ToU16(C); 74348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } 74448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } 74548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } 74648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 74748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 748a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.comvoid SkXfermode::xferA8(SkAlpha* SK_RESTRICT dst, 74948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org const SkPMColor src[], int count, 75030da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.com const SkAlpha* SK_RESTRICT aa) const { 75148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkASSERT(dst && src && count >= 0); 75248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 75348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org if (NULL == aa) { 75448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org for (int i = count - 1; i >= 0; --i) { 75548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkPMColor res = this->xferColor(src[i], (dst[i] << SK_A32_SHIFT)); 75648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org dst[i] = SkToU8(SkGetPackedA32(res)); 75748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } 75848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } else { 75948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org for (int i = count - 1; i >= 0; --i) { 76048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org unsigned a = aa[i]; 76148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org if (0 != a) { 76248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkAlpha dstA = dst[i]; 76348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org unsigned A = SkGetPackedA32(this->xferColor(src[i], 76448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org (SkPMColor)(dstA << SK_A32_SHIFT))); 76548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org if (0xFF != a) { 76648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org A = SkAlphaBlend(A, dstA, SkAlpha255To256(a)); 76748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } 76848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org dst[i] = SkToU8(A); 76948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } 77048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } 77148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } 77248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 77348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 77426e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com////////////////////////////////////////////////////////////////////////////// 77526e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com 77626e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com#if SK_SUPPORT_GPU 77726e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com 778b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#include "GrProcessor.h" 77977af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com#include "GrCoordTransform.h" 780b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#include "GrProcessorUnitTest.h" 781b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#include "GrTBackendProcessorFactory.h" 782b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#include "gl/GrGLProcessor.h" 78330ba436f04e61d4505fb854d5fc56079636e0788joshualitt#include "gl/builders/GrGLProgramBuilder.h" 78426e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com 78526e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com/** 786b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt * GrProcessor that implements the all the separable xfer modes that cannot be expressed as Coeffs. 78726e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com */ 788b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass XferEffect : public GrFragmentProcessor { 78926e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.compublic: 7908da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com static bool IsSupportedMode(SkXfermode::Mode mode) { 79177cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com return mode > SkXfermode::kLastCoeffMode && mode <= SkXfermode::kLastMode; 7928da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com } 7938da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com 794b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt static GrFragmentProcessor* Create(SkXfermode::Mode mode, GrTexture* background) { 7958da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com if (!IsSupportedMode(mode)) { 7968da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com return NULL; 7978da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com } else { 79855fad7af61c21d502acb9891d631e8aa29e3628cbsalomon return SkNEW_ARGS(XferEffect, (mode, background)); 7998da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com } 80026e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com } 80126e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com 80226e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com virtual void getConstantColorComponents(GrColor* color, 80326e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com uint32_t* validFlags) const SK_OVERRIDE { 80426e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com *validFlags = 0; 80526e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com } 80626e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com 807b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE { 808b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt return GrTBackendFragmentProcessorFactory<XferEffect>::getInstance(); 80926e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com } 81026e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com 8118da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com static const char* Name() { return "XferEffect"; } 8128da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com 8138da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com SkXfermode::Mode mode() const { return fMode; } 81486fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org const GrTextureAccess& backgroundAccess() const { return fBackgroundAccess; } 81526e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com 816b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt class GLProcessor : public GrGLFragmentProcessor { 81726e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com public: 818b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GLProcessor(const GrBackendProcessorFactory& factory, const GrProcessor&) 819b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt : INHERITED(factory) { 82026e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com } 82130ba436f04e61d4505fb854d5fc56079636e0788joshualitt virtual void emitCode(GrGLProgramBuilder* builder, 822b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrFragmentProcessor& fp, 823b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrProcessorKey& key, 82426e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com const char* outputColor, 82526e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com const char* inputColor, 82677af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com const TransformedCoordsArray& coords, 82726e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com const TextureSamplerArray& samplers) SK_OVERRIDE { 828b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt SkXfermode::Mode mode = fp.cast<XferEffect>().mode(); 82949586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt const GrTexture* backgroundTex = 830b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt fp.cast<XferEffect>().backgroundAccess().getTexture(); 83130ba436f04e61d4505fb854d5fc56079636e0788joshualitt GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder(); 83286fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org const char* dstColor; 83386fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org if (backgroundTex) { 83486fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org dstColor = "bgColor"; 83530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\tvec4 %s = ", dstColor); 83623e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt fsBuilder->appendTextureLookup(samplers[0], coords[0].c_str(), coords[0].getType()); 83730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf(";\n"); 83886fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org } else { 83930ba436f04e61d4505fb854d5fc56079636e0788joshualitt dstColor = fsBuilder->dstColor(); 84086fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org } 84149f085dddff10473b6ebf832a974288300224e60bsalomon SkASSERT(dstColor); 8428da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com 8438da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com // We don't try to optimize for this case at all 844b79d865f03456b67273b568fa5046b8ba01e365absalomon@google.com if (NULL == inputColor) { 84530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\tconst vec4 ones = vec4(1);\n"); 8468da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com inputColor = "ones"; 8478da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com } 84830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t// SkXfermode::Mode: %s\n", SkXfermode::ModeName(mode)); 84977cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com 8508da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com // These all perform src-over on the alpha channel. 85130ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t%s.a = %s.a + (1.0 - %s.a) * %s.a;\n", 8528da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com outputColor, inputColor, inputColor, dstColor); 8538da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com 85477cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com switch (mode) { 8558da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com case SkXfermode::kOverlay_Mode: 8568da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com // Overlay is Hard-Light with the src and dst reversed 85730ba436f04e61d4505fb854d5fc56079636e0788joshualitt HardLight(fsBuilder, outputColor, dstColor, inputColor); 8588da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com break; 8598da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com case SkXfermode::kDarken_Mode: 86030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t%s.rgb = min((1.0 - %s.a) * %s.rgb + %s.rgb, " 8618da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com "(1.0 - %s.a) * %s.rgb + %s.rgb);\n", 8628da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com outputColor, 8638da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com inputColor, dstColor, inputColor, 8648da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com dstColor, inputColor, dstColor); 8658da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com break; 8668da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com case SkXfermode::kLighten_Mode: 86730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t%s.rgb = max((1.0 - %s.a) * %s.rgb + %s.rgb, " 8688da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com "(1.0 - %s.a) * %s.rgb + %s.rgb);\n", 8698da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com outputColor, 8708da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com inputColor, dstColor, inputColor, 8718da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com dstColor, inputColor, dstColor); 8728da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com break; 8738da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com case SkXfermode::kColorDodge_Mode: 87430ba436f04e61d4505fb854d5fc56079636e0788joshualitt ColorDodgeComponent(fsBuilder, outputColor, inputColor, dstColor, 'r'); 87530ba436f04e61d4505fb854d5fc56079636e0788joshualitt ColorDodgeComponent(fsBuilder, outputColor, inputColor, dstColor, 'g'); 87630ba436f04e61d4505fb854d5fc56079636e0788joshualitt ColorDodgeComponent(fsBuilder, outputColor, inputColor, dstColor, 'b'); 8778da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com break; 8788da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com case SkXfermode::kColorBurn_Mode: 87930ba436f04e61d4505fb854d5fc56079636e0788joshualitt ColorBurnComponent(fsBuilder, outputColor, inputColor, dstColor, 'r'); 88030ba436f04e61d4505fb854d5fc56079636e0788joshualitt ColorBurnComponent(fsBuilder, outputColor, inputColor, dstColor, 'g'); 88130ba436f04e61d4505fb854d5fc56079636e0788joshualitt ColorBurnComponent(fsBuilder, outputColor, inputColor, dstColor, 'b'); 8828da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com break; 8838da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com case SkXfermode::kHardLight_Mode: 88430ba436f04e61d4505fb854d5fc56079636e0788joshualitt HardLight(fsBuilder, outputColor, inputColor, dstColor); 8858da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com break; 8868da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com case SkXfermode::kSoftLight_Mode: 88730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\tif (0.0 == %s.a) {\n", dstColor); 88830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t\t%s.rgba = %s;\n", outputColor, inputColor); 88930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t} else {\n"); 89030ba436f04e61d4505fb854d5fc56079636e0788joshualitt SoftLightComponentPosDstAlpha(fsBuilder, outputColor, inputColor, dstColor, 'r'); 89130ba436f04e61d4505fb854d5fc56079636e0788joshualitt SoftLightComponentPosDstAlpha(fsBuilder, outputColor, inputColor, dstColor, 'g'); 89230ba436f04e61d4505fb854d5fc56079636e0788joshualitt SoftLightComponentPosDstAlpha(fsBuilder, outputColor, inputColor, dstColor, 'b'); 89330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t}\n"); 8948da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com break; 8958da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com case SkXfermode::kDifference_Mode: 89630ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t%s.rgb = %s.rgb + %s.rgb -" 89764b682ca42c75667e49251d3ab04f192f92d0dd8skia.committer@gmail.com "2.0 * min(%s.rgb * %s.a, %s.rgb * %s.a);\n", 8988da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com outputColor, inputColor, dstColor, inputColor, dstColor, 8998da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com dstColor, inputColor); 9008da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com break; 9018da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com case SkXfermode::kExclusion_Mode: 90230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t%s.rgb = %s.rgb + %s.rgb - " 9038da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com "2.0 * %s.rgb * %s.rgb;\n", 9048da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com outputColor, dstColor, inputColor, dstColor, inputColor); 9058da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com break; 9068da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com case SkXfermode::kMultiply_Mode: 90730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t%s.rgb = (1.0 - %s.a) * %s.rgb + " 9088da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com "(1.0 - %s.a) * %s.rgb + " 9098da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com "%s.rgb * %s.rgb;\n", 9108da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com outputColor, inputColor, dstColor, dstColor, inputColor, 9118da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com inputColor, dstColor); 9128da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com break; 91377cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com case SkXfermode::kHue_Mode: { 91477cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com // SetLum(SetSat(S * Da, Sat(D * Sa)), Sa*Da, D*Sa) + (1 - Sa) * D + (1 - Da) * S 91577cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com SkString setSat, setLum; 91630ba436f04e61d4505fb854d5fc56079636e0788joshualitt AddSatFunction(fsBuilder, &setSat); 91730ba436f04e61d4505fb854d5fc56079636e0788joshualitt AddLumFunction(fsBuilder, &setLum); 91830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\tvec4 dstSrcAlpha = %s * %s.a;\n", 91977cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com dstColor, inputColor); 92030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t%s.rgb = %s(%s(%s.rgb * %s.a, dstSrcAlpha.rgb), dstSrcAlpha.a, dstSrcAlpha.rgb);\n", 92177cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com outputColor, setLum.c_str(), setSat.c_str(), inputColor, 92277cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com dstColor); 92330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t%s.rgb += (1.0 - %s.a) * %s.rgb + (1.0 - %s.a) * %s.rgb;\n", 92477cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com outputColor, inputColor, dstColor, dstColor, inputColor); 92577cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com break; 92677cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com } 92777cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com case SkXfermode::kSaturation_Mode: { 92877cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com // SetLum(SetSat(D * Sa, Sat(S * Da)), Sa*Da, D*Sa)) + (1 - Sa) * D + (1 - Da) * S 92977cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com SkString setSat, setLum; 93030ba436f04e61d4505fb854d5fc56079636e0788joshualitt AddSatFunction(fsBuilder, &setSat); 93130ba436f04e61d4505fb854d5fc56079636e0788joshualitt AddLumFunction(fsBuilder, &setLum); 93230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\tvec4 dstSrcAlpha = %s * %s.a;\n", 93377cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com dstColor, inputColor); 93430ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t%s.rgb = %s(%s(dstSrcAlpha.rgb, %s.rgb * %s.a), dstSrcAlpha.a, dstSrcAlpha.rgb);\n", 93577cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com outputColor, setLum.c_str(), setSat.c_str(), inputColor, 93677cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com dstColor); 93730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t%s.rgb += (1.0 - %s.a) * %s.rgb + (1.0 - %s.a) * %s.rgb;\n", 93877cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com outputColor, inputColor, dstColor, dstColor, inputColor); 9398da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com break; 94077cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com } 94177cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com case SkXfermode::kColor_Mode: { 94277cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com // SetLum(S * Da, Sa* Da, D * Sa) + (1 - Sa) * D + (1 - Da) * S 94377cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com SkString setLum; 94430ba436f04e61d4505fb854d5fc56079636e0788joshualitt AddLumFunction(fsBuilder, &setLum); 94530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\tvec4 srcDstAlpha = %s * %s.a;\n", 94677cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com inputColor, dstColor); 94730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t%s.rgb = %s(srcDstAlpha.rgb, srcDstAlpha.a, %s.rgb * %s.a);\n", 94877cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com outputColor, setLum.c_str(), dstColor, inputColor); 94930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t%s.rgb += (1.0 - %s.a) * %s.rgb + (1.0 - %s.a) * %s.rgb;\n", 95077cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com outputColor, inputColor, dstColor, dstColor, inputColor); 95177cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com break; 95277cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com } 95377cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com case SkXfermode::kLuminosity_Mode: { 95477cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com // SetLum(D * Sa, Sa* Da, S * Da) + (1 - Sa) * D + (1 - Da) * S 95577cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com SkString setLum; 95630ba436f04e61d4505fb854d5fc56079636e0788joshualitt AddLumFunction(fsBuilder, &setLum); 95730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\tvec4 srcDstAlpha = %s * %s.a;\n", 95877cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com inputColor, dstColor); 95930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t%s.rgb = %s(%s.rgb * %s.a, srcDstAlpha.a, srcDstAlpha.rgb);\n", 96077cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com outputColor, setLum.c_str(), dstColor, inputColor); 96130ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t%s.rgb += (1.0 - %s.a) * %s.rgb + (1.0 - %s.a) * %s.rgb;\n", 96277cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com outputColor, inputColor, dstColor, dstColor, inputColor); 96377cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com break; 96477cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com } 9658da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com default: 96688cb22b6b4816c7a9ca6c5b795965b4606f9eb7bcommit-bot@chromium.org SkFAIL("Unknown XferEffect mode."); 9678da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com break; 968b79d865f03456b67273b568fa5046b8ba01e365absalomon@google.com } 96926e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com } 97026e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com 971b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt static inline void GenKey(const GrProcessor& proc, const GrGLCaps&, 972b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessorKeyBuilder* b) { 973372a9c3f443bdcc60b0e0c17f028461eaaed5fd1commit-bot@chromium.org // The background may come from the dst or from a texture. 974b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt uint32_t key = proc.numTextures(); 97563e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon SkASSERT(key <= 1); 976b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt key |= proc.cast<XferEffect>().mode() << 1; 97763e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon b->add32(key); 97886fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org } 97926e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com 98026e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com private: 98130ba436f04e61d4505fb854d5fc56079636e0788joshualitt static void HardLight(GrGLFragmentShaderBuilder* fsBuilder, 9828da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com const char* final, 9838da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com const char* src, 9848da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com const char* dst) { 985a0d91388bb6d3d18b7409dbc1654a4335b051ae5commit-bot@chromium.org static const char kComponents[] = {'r', 'g', 'b'}; 986a0d91388bb6d3d18b7409dbc1654a4335b051ae5commit-bot@chromium.org for (size_t i = 0; i < SK_ARRAY_COUNT(kComponents); ++i) { 987a0d91388bb6d3d18b7409dbc1654a4335b051ae5commit-bot@chromium.org char component = kComponents[i]; 98830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\tif (2.0 * %s.%c <= %s.a) {\n", src, component, src); 98930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t\t%s.%c = 2.0 * %s.%c * %s.%c;\n", final, component, src, component, dst, component); 99030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t\t} else {\n"); 99130ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t\t%s.%c = %s.a * %s.a - 2.0 * (%s.a - %s.%c) * (%s.a - %s.%c);\n", 992a0d91388bb6d3d18b7409dbc1654a4335b051ae5commit-bot@chromium.org final, component, src, dst, dst, dst, component, src, src, component); 99330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t\t}\n"); 994a0d91388bb6d3d18b7409dbc1654a4335b051ae5commit-bot@chromium.org } 99530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t%s.rgb += %s.rgb * (1.0 - %s.a) + %s.rgb * (1.0 - %s.a);\n", 9968da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com final, src, dst, dst, src); 9978da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com } 9988da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com 9998da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com // Does one component of color-dodge 100030ba436f04e61d4505fb854d5fc56079636e0788joshualitt static void ColorDodgeComponent(GrGLFragmentShaderBuilder* fsBuilder, 10018da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com const char* final, 10028da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com const char* src, 10038da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com const char* dst, 10048da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com const char component) { 100530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\tif (0.0 == %s.%c) {\n", dst, component); 100630ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t\t%s.%c = %s.%c * (1.0 - %s.a);\n", 10078da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com final, component, src, component, dst); 100830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t\t} else {\n"); 100930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t\tfloat d = %s.a - %s.%c;\n", src, src, component); 101030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t\t\tif (0.0 == d) {\n"); 101130ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t\t\t%s.%c = %s.a * %s.a + %s.%c * (1.0 - %s.a) + %s.%c * (1.0 - %s.a);\n", 10128da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com final, component, src, dst, src, component, dst, dst, component, 10138da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com src); 101430ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t\t\t} else {\n"); 101530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t\t\td = min(%s.a, %s.%c * %s.a / d);\n", 10168da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com dst, dst, component, src); 101730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t\t\t%s.%c = d * %s.a + %s.%c * (1.0 - %s.a) + %s.%c * (1.0 - %s.a);\n", 10188da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com final, component, src, src, component, dst, dst, component, src); 101930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t\t\t}\n"); 102030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t\t}\n"); 10218da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com } 10228da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com 10238da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com // Does one component of color-burn 102430ba436f04e61d4505fb854d5fc56079636e0788joshualitt static void ColorBurnComponent(GrGLFragmentShaderBuilder* fsBuilder, 10258da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com const char* final, 10268da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com const char* src, 10278da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com const char* dst, 10288da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com const char component) { 102930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\tif (%s.a == %s.%c) {\n", dst, dst, component); 103030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t\t%s.%c = %s.a * %s.a + %s.%c * (1.0 - %s.a) + %s.%c * (1.0 - %s.a);\n", 10318da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com final, component, src, dst, src, component, dst, dst, component, 10328da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com src); 103330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t} else if (0.0 == %s.%c) {\n", src, component); 103430ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t\t%s.%c = %s.%c * (1.0 - %s.a);\n", 10358da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com final, component, dst, component, src); 103630ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t\t} else {\n"); 103730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t\tfloat d = max(0.0, %s.a - (%s.a - %s.%c) * %s.a / %s.%c);\n", 10388da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com dst, dst, dst, component, src, src, component); 103930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t\t%s.%c = %s.a * d + %s.%c * (1.0 - %s.a) + %s.%c * (1.0 - %s.a);\n", 10408da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com final, component, src, src, component, dst, dst, component, src); 104130ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t\t}\n"); 10428da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com } 10438da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com 10448da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com // Does one component of soft-light. Caller should have already checked that dst alpha > 0. 104530ba436f04e61d4505fb854d5fc56079636e0788joshualitt static void SoftLightComponentPosDstAlpha(GrGLFragmentShaderBuilder* fsBuilder, 10468da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com const char* final, 10478da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com const char* src, 10488da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com const char* dst, 10498da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com const char component) { 10508da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com // if (2S < Sa) 105130ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t\tif (2.0 * %s.%c <= %s.a) {\n", src, component, src); 10528da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com // (D^2 (Sa-2 S))/Da+(1-Da) S+D (-Sa+2 S+1) 105330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t\t\t%s.%c = (%s.%c*%s.%c*(%s.a - 2.0*%s.%c)) / %s.a + (1.0 - %s.a) * %s.%c + %s.%c*(-%s.a + 2.0*%s.%c + 1.0);\n", 10548da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com final, component, dst, component, dst, component, src, src, 10558da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com component, dst, dst, src, component, dst, component, src, src, 10568da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com component); 10578da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com // else if (4D < Da) 105830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t\t} else if (4.0 * %s.%c <= %s.a) {\n", 10598da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com dst, component, dst); 106030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t\t\tfloat DSqd = %s.%c * %s.%c;\n", 10618da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com dst, component, dst, component); 106230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t\t\tfloat DCub = DSqd * %s.%c;\n", dst, component); 106330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t\t\tfloat DaSqd = %s.a * %s.a;\n", dst, dst); 106430ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t\t\tfloat DaCub = DaSqd * %s.a;\n", dst); 10658da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com // (Da^3 (-S)+Da^2 (S-D (3 Sa-6 S-1))+12 Da D^2 (Sa-2 S)-16 D^3 (Sa-2 S))/Da^2 106630ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t\t\t%s.%c = (-DaCub*%s.%c + DaSqd*(%s.%c - %s.%c * (3.0*%s.a - 6.0*%s.%c - 1.0)) + 12.0*%s.a*DSqd*(%s.a - 2.0*%s.%c) - 16.0*DCub * (%s.a - 2.0*%s.%c)) / DaSqd;\n", 10678da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com final, component, src, component, src, component, dst, component, 10688da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com src, src, component, dst, src, src, component, src, src, 10698da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com component); 107030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t\t} else {\n"); 10718da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com // -sqrt(Da * D) (Sa-2 S)-Da S+D (Sa-2 S+1)+S 107230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t\t\t%s.%c = -sqrt(%s.a*%s.%c)*(%s.a - 2.0*%s.%c) - %s.a*%s.%c + %s.%c*(%s.a - 2.0*%s.%c + 1.0) + %s.%c;\n", 10738da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com final, component, dst, dst, component, src, src, component, dst, 10748da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com src, component, dst, component, src, src, component, src, 10758da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com component); 107630ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t\t}\n"); 10778da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com } 10788da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com 107977cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com // Adds a function that takes two colors and an alpha as input. It produces a color with the 108077cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com // hue and saturation of the first color, the luminosity of the second color, and the input 108177cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com // alpha. It has this signature: 108277cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com // vec3 set_luminance(vec3 hueSatColor, float alpha, vec3 lumColor). 108330ba436f04e61d4505fb854d5fc56079636e0788joshualitt static void AddLumFunction(GrGLFragmentShaderBuilder* fsBuilder, SkString* setLumFunction) { 108477cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com // Emit a helper that gets the luminance of a color. 108577cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com SkString getFunction; 108677cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com GrGLShaderVar getLumArgs[] = { 108777cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com GrGLShaderVar("color", kVec3f_GrSLType), 108877cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com }; 108977cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com SkString getLumBody("\treturn dot(vec3(0.3, 0.59, 0.11), color);\n"); 109030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->emitFunction(kFloat_GrSLType, 109174a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org "luminance", 109274a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org SK_ARRAY_COUNT(getLumArgs), getLumArgs, 109374a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org getLumBody.c_str(), 109474a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org &getFunction); 109577cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com 109677cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com // Emit the set luminance function. 109777cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com GrGLShaderVar setLumArgs[] = { 109877cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com GrGLShaderVar("hueSat", kVec3f_GrSLType), 109977cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com GrGLShaderVar("alpha", kFloat_GrSLType), 110077cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com GrGLShaderVar("lumColor", kVec3f_GrSLType), 110177cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com }; 110277cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com SkString setLumBody; 110377cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com setLumBody.printf("\tfloat diff = %s(lumColor - hueSat);\n", getFunction.c_str()); 110477cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com setLumBody.append("\tvec3 outColor = hueSat + diff;\n"); 110577cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com setLumBody.appendf("\tfloat outLum = %s(outColor);\n", getFunction.c_str()); 110677cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com setLumBody.append("\tfloat minComp = min(min(outColor.r, outColor.g), outColor.b);\n" 110777cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com "\tfloat maxComp = max(max(outColor.r, outColor.g), outColor.b);\n" 110877cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com "\tif (minComp < 0.0) {\n" 110977cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com "\t\toutColor = outLum + ((outColor - vec3(outLum, outLum, outLum)) * outLum) / (outLum - minComp);\n" 111077cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com "\t}\n" 111177cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com "\tif (maxComp > alpha) {\n" 111277cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com "\t\toutColor = outLum + ((outColor - vec3(outLum, outLum, outLum)) * (alpha - outLum)) / (maxComp - outLum);\n" 111377cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com "\t}\n" 111477cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com "\treturn outColor;\n"); 111530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->emitFunction(kVec3f_GrSLType, 111674a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org "set_luminance", 111774a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org SK_ARRAY_COUNT(setLumArgs), setLumArgs, 111874a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org setLumBody.c_str(), 111974a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org setLumFunction); 112077cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com } 112177cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com 112277cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com // Adds a function that creates a color with the hue and luminosity of one input color and 112377cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com // the saturation of another color. It will have this signature: 112477cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com // float set_saturation(vec3 hueLumColor, vec3 satColor) 112530ba436f04e61d4505fb854d5fc56079636e0788joshualitt static void AddSatFunction(GrGLFragmentShaderBuilder* fsBuilder, SkString* setSatFunction) { 112677cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com // Emit a helper that gets the saturation of a color 112777cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com SkString getFunction; 112877cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com GrGLShaderVar getSatArgs[] = { GrGLShaderVar("color", kVec3f_GrSLType) }; 112977cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com SkString getSatBody; 113077cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com getSatBody.printf("\treturn max(max(color.r, color.g), color.b) - " 113177cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com "min(min(color.r, color.g), color.b);\n"); 113230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->emitFunction(kFloat_GrSLType, 113374a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org "saturation", 113474a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org SK_ARRAY_COUNT(getSatArgs), getSatArgs, 113574a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org getSatBody.c_str(), 113674a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org &getFunction); 113777cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com 1138c718b35bce895aa945fc479451156985206fdae1commit-bot@chromium.org // Emit a helper that sets the saturation given sorted input channels. This used 1139c718b35bce895aa945fc479451156985206fdae1commit-bot@chromium.org // to use inout params for min, mid, and max components but that seems to cause 1140c718b35bce895aa945fc479451156985206fdae1commit-bot@chromium.org // problems on PowerVR drivers. So instead it returns a vec3 where r, g ,b are the 1141c718b35bce895aa945fc479451156985206fdae1commit-bot@chromium.org // adjusted min, mid, and max inputs, respectively. 114277cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com SkString helperFunction; 114377cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com GrGLShaderVar helperArgs[] = { 114477cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com GrGLShaderVar("minComp", kFloat_GrSLType), 114577cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com GrGLShaderVar("midComp", kFloat_GrSLType), 114677cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com GrGLShaderVar("maxComp", kFloat_GrSLType), 114777cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com GrGLShaderVar("sat", kFloat_GrSLType), 114877cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com }; 1149c718b35bce895aa945fc479451156985206fdae1commit-bot@chromium.org static const char kHelperBody[] = "\tif (minComp < maxComp) {\n" 1150c718b35bce895aa945fc479451156985206fdae1commit-bot@chromium.org "\t\tvec3 result;\n" 1151c718b35bce895aa945fc479451156985206fdae1commit-bot@chromium.org "\t\tresult.r = 0.0;\n" 1152c718b35bce895aa945fc479451156985206fdae1commit-bot@chromium.org "\t\tresult.g = sat * (midComp - minComp) / (maxComp - minComp);\n" 1153c718b35bce895aa945fc479451156985206fdae1commit-bot@chromium.org "\t\tresult.b = sat;\n" 1154c718b35bce895aa945fc479451156985206fdae1commit-bot@chromium.org "\t\treturn result;\n" 1155c718b35bce895aa945fc479451156985206fdae1commit-bot@chromium.org "\t} else {\n" 1156c718b35bce895aa945fc479451156985206fdae1commit-bot@chromium.org "\t\treturn vec3(0, 0, 0);\n" 1157c718b35bce895aa945fc479451156985206fdae1commit-bot@chromium.org "\t}\n"; 115830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->emitFunction(kVec3f_GrSLType, 115974a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org "set_saturation_helper", 116074a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org SK_ARRAY_COUNT(helperArgs), helperArgs, 116174a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org kHelperBody, 116274a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org &helperFunction); 116377cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com 116477cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com GrGLShaderVar setSatArgs[] = { 116577cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com GrGLShaderVar("hueLumColor", kVec3f_GrSLType), 116677cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com GrGLShaderVar("satColor", kVec3f_GrSLType), 116777cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com }; 116877cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com const char* helpFunc = helperFunction.c_str(); 116977cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com SkString setSatBody; 117077cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com setSatBody.appendf("\tfloat sat = %s(satColor);\n" 117177cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com "\tif (hueLumColor.r <= hueLumColor.g) {\n" 117277cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com "\t\tif (hueLumColor.g <= hueLumColor.b) {\n" 1173c718b35bce895aa945fc479451156985206fdae1commit-bot@chromium.org "\t\t\thueLumColor.rgb = %s(hueLumColor.r, hueLumColor.g, hueLumColor.b, sat);\n" 117418c41acf35eefc75ef4631fbb680ec64861b30afcommit-bot@chromium.org "\t\t} else if (hueLumColor.r <= hueLumColor.b) {\n" 1175c718b35bce895aa945fc479451156985206fdae1commit-bot@chromium.org "\t\t\thueLumColor.rbg = %s(hueLumColor.r, hueLumColor.b, hueLumColor.g, sat);\n" 117618c41acf35eefc75ef4631fbb680ec64861b30afcommit-bot@chromium.org "\t\t} else {\n" 1177c718b35bce895aa945fc479451156985206fdae1commit-bot@chromium.org "\t\t\thueLumColor.brg = %s(hueLumColor.b, hueLumColor.r, hueLumColor.g, sat);\n" 117877cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com "\t\t}\n" 117977cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com "\t} else if (hueLumColor.r <= hueLumColor.b) {\n" 1180c718b35bce895aa945fc479451156985206fdae1commit-bot@chromium.org "\t\thueLumColor.grb = %s(hueLumColor.g, hueLumColor.r, hueLumColor.b, sat);\n" 118177cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com "\t} else if (hueLumColor.g <= hueLumColor.b) {\n" 1182c718b35bce895aa945fc479451156985206fdae1commit-bot@chromium.org "\t\thueLumColor.gbr = %s(hueLumColor.g, hueLumColor.b, hueLumColor.r, sat);\n" 118377cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com "\t} else {\n" 1184c718b35bce895aa945fc479451156985206fdae1commit-bot@chromium.org "\t\thueLumColor.bgr = %s(hueLumColor.b, hueLumColor.g, hueLumColor.r, sat);\n" 118577cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com "\t}\n" 1186c718b35bce895aa945fc479451156985206fdae1commit-bot@chromium.org "\treturn hueLumColor;\n", 118718c41acf35eefc75ef4631fbb680ec64861b30afcommit-bot@chromium.org getFunction.c_str(), helpFunc, helpFunc, helpFunc, helpFunc, 118818c41acf35eefc75ef4631fbb680ec64861b30afcommit-bot@chromium.org helpFunc, helpFunc); 118930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->emitFunction(kVec3f_GrSLType, 119074a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org "set_saturation", 119174a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org SK_ARRAY_COUNT(setSatArgs), setSatArgs, 119274a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org setSatBody.c_str(), 119374a3a2135ca82ab9324b7e499caa3280348a4fdacommit-bot@chromium.org setSatFunction); 119477cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com 119577cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com } 119677cf460e5df7dd5272e71f9835880ded48fe8d12bsalomon@google.com 1197b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt typedef GrGLFragmentProcessor INHERITED; 119826e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com }; 119926e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com 1200b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GR_DECLARE_FRAGMENT_PROCESSOR_TEST; 120126e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com 120226e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.comprivate: 120386fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org XferEffect(SkXfermode::Mode mode, GrTexture* background) 120486fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org : fMode(mode) { 120586fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org if (background) { 120677af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com fBackgroundTransform.reset(kLocal_GrCoordSet, background); 120777af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com this->addCoordTransform(&fBackgroundTransform); 120886fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org fBackgroundAccess.reset(background); 120986fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org this->addTextureAccess(&fBackgroundAccess); 121086fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org } else { 121186fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org this->setWillReadDstColor(); 121286fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org } 121386fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org } 1214b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE { 121549586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt const XferEffect& s = other.cast<XferEffect>(); 121686fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org return fMode == s.fMode && 121786fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org fBackgroundAccess.getTexture() == s.fBackgroundAccess.getTexture(); 121886fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org } 121964b682ca42c75667e49251d3ab04f192f92d0dd8skia.committer@gmail.com 12208da9bc751e1898d50dd84d7e5ca666b00e4ff624bsalomon@google.com SkXfermode::Mode fMode; 122177af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com GrCoordTransform fBackgroundTransform; 122286fc266eda887920e3dd104bee8121ae19729cf5senorblanco@chromium.org GrTextureAccess fBackgroundAccess; 122326e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com 1224b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt typedef GrFragmentProcessor INHERITED; 122526e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com}; 122626e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com 1227b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGR_DEFINE_FRAGMENT_PROCESSOR_TEST(XferEffect); 1228b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrFragmentProcessor* XferEffect::TestCreate(SkRandom* rand, 1229b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrContext*, 1230b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrDrawTargetCaps&, 1231b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrTexture*[]) { 1232a0d91388bb6d3d18b7409dbc1654a4335b051ae5commit-bot@chromium.org int mode = rand->nextRangeU(SkXfermode::kLastCoeffMode + 1, SkXfermode::kLastSeparableMode); 12332cf444f7040614b43af67e368f3aa636ebeaa45askia.committer@gmail.com 123455fad7af61c21d502acb9891d631e8aa29e3628cbsalomon return SkNEW_ARGS(XferEffect, (static_cast<SkXfermode::Mode>(mode), NULL)); 123526e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com} 123626e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com 123726e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com#endif 123826e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com 123948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org/////////////////////////////////////////////////////////////////////////////// 124048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org/////////////////////////////////////////////////////////////////////////////// 1241a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com 12429fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING 12438b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgSkProcCoeffXfermode::SkProcCoeffXfermode(SkReadBuffer& buffer) : INHERITED(buffer) { 124452314f82ba8696e957e70eabde672b6470fedf7areed@google.com uint32_t mode32 = buffer.read32() % SK_ARRAY_COUNT(gProcCoeffs); 124552314f82ba8696e957e70eabde672b6470fedf7areed@google.com if (mode32 >= SK_ARRAY_COUNT(gProcCoeffs)) { 124652314f82ba8696e957e70eabde672b6470fedf7areed@google.com // out of range, just set to something harmless 124752314f82ba8696e957e70eabde672b6470fedf7areed@google.com mode32 = SkXfermode::kSrcOut_Mode; 124852314f82ba8696e957e70eabde672b6470fedf7areed@google.com } 124952314f82ba8696e957e70eabde672b6470fedf7areed@google.com fMode = (SkXfermode::Mode)mode32; 1250f61ebc0927d773fe4152a3521cdc3de0112f636eskia.committer@gmail.com 125152314f82ba8696e957e70eabde672b6470fedf7areed@google.com const ProcCoeff& rec = gProcCoeffs[fMode]; 1252cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org fProc = rec.fProc; 125352314f82ba8696e957e70eabde672b6470fedf7areed@google.com // these may be valid, or may be CANNOT_USE_COEFF 125452314f82ba8696e957e70eabde672b6470fedf7areed@google.com fSrcCoeff = rec.fSC; 125552314f82ba8696e957e70eabde672b6470fedf7areed@google.com fDstCoeff = rec.fDC; 125652314f82ba8696e957e70eabde672b6470fedf7areed@google.com} 12579fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#endif 12589fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed 12599fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reedSkFlattenable* SkProcCoeffXfermode::CreateProc(SkReadBuffer& buffer) { 12609fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed uint32_t mode32 = buffer.read32(); 12610f7197bc0ddbe6c61732d6fe69df86bdba00a060senorblanco if (!buffer.validate(mode32 < SK_ARRAY_COUNT(gProcCoeffs))) { 12629fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed return NULL; 12639fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed } 12649fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed return SkXfermode::Create((SkXfermode::Mode)mode32); 12659fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed} 12669fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed 12679fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reedvoid SkProcCoeffXfermode::flatten(SkWriteBuffer& buffer) const { 12689fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed buffer.write32(fMode); 12699fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed} 127052314f82ba8696e957e70eabde672b6470fedf7areed@google.com 1271df187c7eb27d7616b75d91f3329deb97c4cd6de2commit-bot@chromium.orgbool SkProcCoeffXfermode::asMode(Mode* mode) const { 1272df187c7eb27d7616b75d91f3329deb97c4cd6de2commit-bot@chromium.org if (mode) { 1273df187c7eb27d7616b75d91f3329deb97c4cd6de2commit-bot@chromium.org *mode = fMode; 127448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } 1275df187c7eb27d7616b75d91f3329deb97c4cd6de2commit-bot@chromium.org return true; 1276df187c7eb27d7616b75d91f3329deb97c4cd6de2commit-bot@chromium.org} 1277c0d4aa2088a0788f9df221497945d2ba1b342f44reed@google.com 1278df187c7eb27d7616b75d91f3329deb97c4cd6de2commit-bot@chromium.orgbool SkProcCoeffXfermode::asCoeff(Coeff* sc, Coeff* dc) const { 1279df187c7eb27d7616b75d91f3329deb97c4cd6de2commit-bot@chromium.org if (CANNOT_USE_COEFF == fSrcCoeff) { 1280df187c7eb27d7616b75d91f3329deb97c4cd6de2commit-bot@chromium.org return false; 1281c0d4aa2088a0788f9df221497945d2ba1b342f44reed@google.com } 1282c0d4aa2088a0788f9df221497945d2ba1b342f44reed@google.com 1283df187c7eb27d7616b75d91f3329deb97c4cd6de2commit-bot@chromium.org if (sc) { 1284df187c7eb27d7616b75d91f3329deb97c4cd6de2commit-bot@chromium.org *sc = fSrcCoeff; 1285df187c7eb27d7616b75d91f3329deb97c4cd6de2commit-bot@chromium.org } 1286df187c7eb27d7616b75d91f3329deb97c4cd6de2commit-bot@chromium.org if (dc) { 1287df187c7eb27d7616b75d91f3329deb97c4cd6de2commit-bot@chromium.org *dc = fDstCoeff; 128884cc1ebc5a4789e93e23c65eb4014ef5b8b0bab4commit-bot@chromium.org } 1289df187c7eb27d7616b75d91f3329deb97c4cd6de2commit-bot@chromium.org return true; 1290df187c7eb27d7616b75d91f3329deb97c4cd6de2commit-bot@chromium.org} 12916f980c6a2354fed70a6258fb4dd4155936660930djsollen@google.com 1292cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.orgvoid SkProcCoeffXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 1293cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org const SkPMColor* SK_RESTRICT src, int count, 1294cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org const SkAlpha* SK_RESTRICT aa) const { 1295cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org SkASSERT(dst && src && count >= 0); 129660bd7519a9db4ddddd95e490f93165e5676f90f5skia.committer@gmail.com 1297cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org SkXfermodeProc proc = fProc; 129860bd7519a9db4ddddd95e490f93165e5676f90f5skia.committer@gmail.com 129949f085dddff10473b6ebf832a974288300224e60bsalomon if (proc) { 1300cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org if (NULL == aa) { 1301cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org for (int i = count - 1; i >= 0; --i) { 1302cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org dst[i] = proc(src[i], dst[i]); 1303cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org } 1304cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org } else { 1305cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org for (int i = count - 1; i >= 0; --i) { 1306cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org unsigned a = aa[i]; 1307cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org if (0 != a) { 1308cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org SkPMColor dstC = dst[i]; 1309cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org SkPMColor C = proc(src[i], dstC); 1310cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org if (a != 0xFF) { 1311cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org C = SkFourByteInterp(C, dstC, a); 1312cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org } 1313cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org dst[i] = C; 1314cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org } 1315cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org } 1316cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org } 1317cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org } 1318cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org} 1319cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org 1320cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.orgvoid SkProcCoeffXfermode::xfer16(uint16_t* SK_RESTRICT dst, 1321cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org const SkPMColor* SK_RESTRICT src, int count, 1322cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org const SkAlpha* SK_RESTRICT aa) const { 1323cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org SkASSERT(dst && src && count >= 0); 132460bd7519a9db4ddddd95e490f93165e5676f90f5skia.committer@gmail.com 1325cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org SkXfermodeProc proc = fProc; 132660bd7519a9db4ddddd95e490f93165e5676f90f5skia.committer@gmail.com 132749f085dddff10473b6ebf832a974288300224e60bsalomon if (proc) { 1328cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org if (NULL == aa) { 1329cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org for (int i = count - 1; i >= 0; --i) { 1330cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org SkPMColor dstC = SkPixel16ToPixel32(dst[i]); 1331cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org dst[i] = SkPixel32ToPixel16_ToU16(proc(src[i], dstC)); 1332cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org } 1333cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org } else { 1334cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org for (int i = count - 1; i >= 0; --i) { 1335cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org unsigned a = aa[i]; 1336cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org if (0 != a) { 1337cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org SkPMColor dstC = SkPixel16ToPixel32(dst[i]); 1338cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org SkPMColor C = proc(src[i], dstC); 1339cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org if (0xFF != a) { 1340cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org C = SkFourByteInterp(C, dstC, a); 1341cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org } 1342cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org dst[i] = SkPixel32ToPixel16_ToU16(C); 1343cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org } 1344cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org } 1345cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org } 1346cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org } 1347cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org} 1348cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org 1349cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.orgvoid SkProcCoeffXfermode::xferA8(SkAlpha* SK_RESTRICT dst, 1350cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org const SkPMColor* SK_RESTRICT src, int count, 1351cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org const SkAlpha* SK_RESTRICT aa) const { 1352cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org SkASSERT(dst && src && count >= 0); 135360bd7519a9db4ddddd95e490f93165e5676f90f5skia.committer@gmail.com 1354cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org SkXfermodeProc proc = fProc; 135560bd7519a9db4ddddd95e490f93165e5676f90f5skia.committer@gmail.com 135649f085dddff10473b6ebf832a974288300224e60bsalomon if (proc) { 1357cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org if (NULL == aa) { 1358cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org for (int i = count - 1; i >= 0; --i) { 1359cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org SkPMColor res = proc(src[i], dst[i] << SK_A32_SHIFT); 1360cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org dst[i] = SkToU8(SkGetPackedA32(res)); 1361cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org } 1362cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org } else { 1363cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org for (int i = count - 1; i >= 0; --i) { 1364cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org unsigned a = aa[i]; 1365cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org if (0 != a) { 1366cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org SkAlpha dstA = dst[i]; 1367cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org SkPMColor res = proc(src[i], dstA << SK_A32_SHIFT); 1368cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org unsigned A = SkGetPackedA32(res); 1369cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org if (0xFF != a) { 1370cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org A = SkAlphaBlend(A, dstA, SkAlpha255To256(a)); 1371cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org } 1372cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org dst[i] = SkToU8(A); 1373cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org } 1374cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org } 1375cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org } 1376cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org } 1377cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org} 1378cc277b729b16c0d8d042f9ae1db6563fb4538d88commit-bot@chromium.org 13796f980c6a2354fed70a6258fb4dd4155936660930djsollen@google.com#if SK_SUPPORT_GPU 1380b0a8a377f832c59cee939ad721e1f87d378b7142joshualittbool SkProcCoeffXfermode::asFragmentProcessor(GrFragmentProcessor** fp, 1381b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrTexture* background) const { 1382df187c7eb27d7616b75d91f3329deb97c4cd6de2commit-bot@chromium.org if (XferEffect::IsSupportedMode(fMode)) { 1383b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt if (fp) { 1384b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt *fp = XferEffect::Create(fMode, background); 1385b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt SkASSERT(*fp); 13866f980c6a2354fed70a6258fb4dd4155936660930djsollen@google.com } 1387df187c7eb27d7616b75d91f3329deb97c4cd6de2commit-bot@chromium.org return true; 1388f51c01328dc52a87c07e056d6fc4eb7452ccac7absalomon@google.com } 1389df187c7eb27d7616b75d91f3329deb97c4cd6de2commit-bot@chromium.org return false; 1390df187c7eb27d7616b75d91f3329deb97c4cd6de2commit-bot@chromium.org} 139126e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com#endif 1392f51c01328dc52a87c07e056d6fc4eb7452ccac7absalomon@google.com 1393d7aaf6034e519ea9b70649c1d344f2f24de90ccbcommit-bot@chromium.orgconst char* SkXfermode::ModeName(Mode mode) { 1394d7aaf6034e519ea9b70649c1d344f2f24de90ccbcommit-bot@chromium.org SkASSERT((unsigned) mode <= (unsigned)kLastMode); 1395d7aaf6034e519ea9b70649c1d344f2f24de90ccbcommit-bot@chromium.org const char* gModeStrings[] = { 1396b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com "Clear", "Src", "Dst", "SrcOver", "DstOver", "SrcIn", "DstIn", 1397b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com "SrcOut", "DstOut", "SrcATop", "DstATop", "Xor", "Plus", 13988d3cd7a170c810e3816bf00220cbef51e7b16795reed@google.com "Modulate", "Screen", "Overlay", "Darken", "Lighten", "ColorDodge", 1399d7aaf6034e519ea9b70649c1d344f2f24de90ccbcommit-bot@chromium.org "ColorBurn", "HardLight", "SoftLight", "Difference", "Exclusion", 1400d7aaf6034e519ea9b70649c1d344f2f24de90ccbcommit-bot@chromium.org "Multiply", "Hue", "Saturation", "Color", "Luminosity" 1401b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com }; 1402d7aaf6034e519ea9b70649c1d344f2f24de90ccbcommit-bot@chromium.org return gModeStrings[mode]; 1403d7aaf6034e519ea9b70649c1d344f2f24de90ccbcommit-bot@chromium.org SK_COMPILE_ASSERT(SK_ARRAY_COUNT(gModeStrings) == kLastMode + 1, mode_count); 1404d7aaf6034e519ea9b70649c1d344f2f24de90ccbcommit-bot@chromium.org} 1405d7aaf6034e519ea9b70649c1d344f2f24de90ccbcommit-bot@chromium.org 14060f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org#ifndef SK_IGNORE_TO_STRING 1407d7aaf6034e519ea9b70649c1d344f2f24de90ccbcommit-bot@chromium.orgvoid SkProcCoeffXfermode::toString(SkString* str) const { 1408d7aaf6034e519ea9b70649c1d344f2f24de90ccbcommit-bot@chromium.org str->append("SkProcCoeffXfermode: "); 1409b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com 1410b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com str->append("mode: "); 1411d7aaf6034e519ea9b70649c1d344f2f24de90ccbcommit-bot@chromium.org str->append(ModeName(fMode)); 1412b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com 1413b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com static const char* gCoeffStrings[kCoeffCount] = { 141498ded84b80918ac1e40224c125922941f3b2eb03skia.committer@gmail.com "Zero", "One", "SC", "ISC", "DC", "IDC", "SA", "ISA", "DA", "IDA" 1415b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com }; 1416b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com 1417b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com str->append(" src: "); 1418b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com if (CANNOT_USE_COEFF == fSrcCoeff) { 1419b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com str->append("can't use"); 1420b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com } else { 1421b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com str->append(gCoeffStrings[fSrcCoeff]); 1422b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com } 1423b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com 1424b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com str->append(" dst: "); 1425b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com if (CANNOT_USE_COEFF == fDstCoeff) { 1426b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com str->append("can't use"); 1427b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com } else { 1428b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com str->append(gCoeffStrings[fDstCoeff]); 1429b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com } 1430b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com} 1431b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com#endif 1432b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com 14338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 14348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkClearXfermode : public SkProcCoeffXfermode { 14368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 14370a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org static SkClearXfermode* Create(const ProcCoeff& rec) { 14380a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org return SkNEW_ARGS(SkClearXfermode, (rec)); 14390a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org } 14408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 144130da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.com virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE; 144230da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.com virtual void xferA8(SkAlpha*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE; 14438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14440f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org SK_TO_STRING_OVERRIDE() 14451447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 14461447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.comprivate: 14470a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org SkClearXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kClear_Mode) {} 14489fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING 14499fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed SkClearXfermode(SkReadBuffer& buffer) : SkProcCoeffXfermode(buffer) {} 14509fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#endif 14511447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 1452b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com typedef SkProcCoeffXfermode INHERITED; 14538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 14548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 145586ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.comvoid SkClearXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 145686ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com const SkPMColor* SK_RESTRICT, int count, 145730da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.com const SkAlpha* SK_RESTRICT aa) const { 145886ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com SkASSERT(dst && count >= 0); 14598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 146086ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com if (NULL == aa) { 146186ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com memset(dst, 0, count << 2); 146286ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com } else { 146386ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com for (int i = count - 1; i >= 0; --i) { 146486ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com unsigned a = aa[i]; 146586ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com if (0xFF == a) { 146686ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com dst[i] = 0; 146786ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com } else if (a != 0) { 146886ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com dst[i] = SkAlphaMulQ(dst[i], SkAlpha255To256(255 - a)); 14698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 14708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 14718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 147286ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com} 147386ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.comvoid SkClearXfermode::xferA8(SkAlpha* SK_RESTRICT dst, 147486ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com const SkPMColor* SK_RESTRICT, int count, 147530da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.com const SkAlpha* SK_RESTRICT aa) const { 147686ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com SkASSERT(dst && count >= 0); 14778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 147886ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com if (NULL == aa) { 147986ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com memset(dst, 0, count); 148086ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com } else { 148186ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com for (int i = count - 1; i >= 0; --i) { 148286ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com unsigned a = aa[i]; 148386ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com if (0xFF == a) { 148486ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com dst[i] = 0; 148586ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com } else if (0 != a) { 148686ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com dst[i] = SkAlphaMulAlpha(dst[i], 255 - a); 14878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 14888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 14898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 149086ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com} 14911447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 14920f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org#ifndef SK_IGNORE_TO_STRING 1493b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.comvoid SkClearXfermode::toString(SkString* str) const { 1494b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com this->INHERITED::toString(str); 1495b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com} 1496b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com#endif 1497b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com 149886ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com/////////////////////////////////////////////////////////////////////////////// 149986ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com 150086ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.comclass SkSrcXfermode : public SkProcCoeffXfermode { 150186ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.compublic: 15020a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org static SkSrcXfermode* Create(const ProcCoeff& rec) { 15030a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org return SkNEW_ARGS(SkSrcXfermode, (rec)); 15040a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org } 150586ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com 150630da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.com virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE; 150730da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.com virtual void xferA8(SkAlpha*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE; 15088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 15090f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org SK_TO_STRING_OVERRIDE() 15101447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 15111447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.comprivate: 15120a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org SkSrcXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kSrc_Mode) {} 15139fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING 15149fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed SkSrcXfermode(SkReadBuffer& buffer) : SkProcCoeffXfermode(buffer) {} 15159fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#endif 1516b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com typedef SkProcCoeffXfermode INHERITED; 15178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 15188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 151986ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.comvoid SkSrcXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 152086ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com const SkPMColor* SK_RESTRICT src, int count, 152130da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.com const SkAlpha* SK_RESTRICT aa) const { 152286ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com SkASSERT(dst && src && count >= 0); 15231447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 152486ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com if (NULL == aa) { 152586ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com memcpy(dst, src, count << 2); 152686ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com } else { 152786ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com for (int i = count - 1; i >= 0; --i) { 152886ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com unsigned a = aa[i]; 152986ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com if (a == 0xFF) { 153086ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com dst[i] = src[i]; 153186ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com } else if (a != 0) { 153286ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com dst[i] = SkFourByteInterp(src[i], dst[i], a); 153386ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com } 153486ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com } 153586ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com } 153686ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com} 153786ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com 153886ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.comvoid SkSrcXfermode::xferA8(SkAlpha* SK_RESTRICT dst, 153986ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com const SkPMColor* SK_RESTRICT src, int count, 154030da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.com const SkAlpha* SK_RESTRICT aa) const { 154186ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com SkASSERT(dst && src && count >= 0); 15421447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 154386ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com if (NULL == aa) { 154486ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com for (int i = count - 1; i >= 0; --i) { 154586ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com dst[i] = SkToU8(SkGetPackedA32(src[i])); 15468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 154786ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com } else { 154886ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com for (int i = count - 1; i >= 0; --i) { 154986ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com unsigned a = aa[i]; 155086ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com if (0 != a) { 155186ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com unsigned srcA = SkGetPackedA32(src[i]); 155286ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com if (a == 0xFF) { 155386ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com dst[i] = SkToU8(srcA); 155486ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com } else { 155586ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com dst[i] = SkToU8(SkAlphaBlend(srcA, dst[i], a)); 155686ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com } 155786ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com } 15588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 15598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 156086ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com} 15610f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org#ifndef SK_IGNORE_TO_STRING 1562b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.comvoid SkSrcXfermode::toString(SkString* str) const { 1563b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com this->INHERITED::toString(str); 1564b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com} 1565b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com#endif 15661447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 156730da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.com/////////////////////////////////////////////////////////////////////////////// 156886ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com 156986ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.comclass SkDstInXfermode : public SkProcCoeffXfermode { 157086ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.compublic: 15710a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org static SkDstInXfermode* Create(const ProcCoeff& rec) { 15720a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org return SkNEW_ARGS(SkDstInXfermode, (rec)); 15730a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org } 157486ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com 157530da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.com virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE; 15761447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 15770f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org SK_TO_STRING_OVERRIDE() 15781447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 15791447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.comprivate: 15800a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org SkDstInXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kDstIn_Mode) {} 15819fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING 15828b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org SkDstInXfermode(SkReadBuffer& buffer) : INHERITED(buffer) {} 15839fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#endif 15841447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 15858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com typedef SkProcCoeffXfermode INHERITED; 15868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 15878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 158886ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.comvoid SkDstInXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 158986ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com const SkPMColor* SK_RESTRICT src, int count, 159030da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.com const SkAlpha* SK_RESTRICT aa) const { 159186ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com SkASSERT(dst && src); 15921447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 159386ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com if (count <= 0) { 159486ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com return; 159586ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com } 159649f085dddff10473b6ebf832a974288300224e60bsalomon if (aa) { 159786ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com return this->INHERITED::xfer32(dst, src, count, aa); 159886ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com } 15991447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 160086ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com do { 160186ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com unsigned a = SkGetPackedA32(*src); 160286ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com *dst = SkAlphaMulQ(*dst, SkAlpha255To256(a)); 160386ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com dst++; 160486ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com src++; 160586ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com } while (--count != 0); 160686ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com} 16071447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 16080f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org#ifndef SK_IGNORE_TO_STRING 1609b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.comvoid SkDstInXfermode::toString(SkString* str) const { 1610b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com this->INHERITED::toString(str); 1611b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com} 1612b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com#endif 1613b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com 161430da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.com/////////////////////////////////////////////////////////////////////////////// 16151447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 161686ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.comclass SkDstOutXfermode : public SkProcCoeffXfermode { 161786ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.compublic: 16180a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org static SkDstOutXfermode* Create(const ProcCoeff& rec) { 16190a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org return SkNEW_ARGS(SkDstOutXfermode, (rec)); 16200a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org } 162186ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com 162230da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.com virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE; 16231447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 16240f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org SK_TO_STRING_OVERRIDE() 16251447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 16261447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.comprivate: 16270a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org SkDstOutXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kDstOut_Mode) {} 16289fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING 16299fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed SkDstOutXfermode(SkReadBuffer& buffer) : INHERITED(buffer) {} 16309fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#endif 16311447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 16328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com typedef SkProcCoeffXfermode INHERITED; 16338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 16348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 163586ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.comvoid SkDstOutXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 163686ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com const SkPMColor* SK_RESTRICT src, int count, 163730da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.com const SkAlpha* SK_RESTRICT aa) const { 163886ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com SkASSERT(dst && src); 163986ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com 164086ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com if (count <= 0) { 164186ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com return; 164286ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com } 164349f085dddff10473b6ebf832a974288300224e60bsalomon if (aa) { 164486ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com return this->INHERITED::xfer32(dst, src, count, aa); 164586ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com } 164686ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com 164786ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com do { 164886ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com unsigned a = SkGetPackedA32(*src); 164986ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com *dst = SkAlphaMulQ(*dst, SkAlpha255To256(255 - a)); 165086ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com dst++; 165186ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com src++; 165286ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com } while (--count != 0); 165386ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com} 165486ab6c694c0b29cb49363746ac6982faa4eef1b2reed@google.com 16550f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org#ifndef SK_IGNORE_TO_STRING 1656b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.comvoid SkDstOutXfermode::toString(SkString* str) const { 1657b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com this->INHERITED::toString(str); 1658b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com} 1659b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com#endif 1660b83b6b4f7690fe929d8d6b1a3d2b7ed562b95ba6robertphillips@google.com 16618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 16628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 166397de357270e54be53acb17e1cb4b4d5e25bacc01commit-bot@chromium.orgextern SkProcCoeffXfermode* SkPlatformXfermodeFactory(const ProcCoeff& rec, SkXfermode::Mode mode); 1664d611864e679a58865b111e74fe7ac919cba42163commit-bot@chromium.orgextern SkXfermodeProc SkPlatformXfermodeProcFactory(SkXfermode::Mode mode); 1665df187c7eb27d7616b75d91f3329deb97c4cd6de2commit-bot@chromium.org 166697de357270e54be53acb17e1cb4b4d5e25bacc01commit-bot@chromium.org// Technically, can't be static and passed as a template parameter. So we use anonymous namespace. 166797de357270e54be53acb17e1cb4b4d5e25bacc01commit-bot@chromium.orgnamespace { 166897de357270e54be53acb17e1cb4b4d5e25bacc01commit-bot@chromium.orgSkXfermode* create_mode(int iMode) { 166997de357270e54be53acb17e1cb4b4d5e25bacc01commit-bot@chromium.org SkXfermode::Mode mode = (SkXfermode::Mode)iMode; 1670140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org 1671140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org ProcCoeff rec = gProcCoeffs[mode]; 1672140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org SkXfermodeProc pp = SkPlatformXfermodeProcFactory(mode); 1673140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org if (pp != NULL) { 1674140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org rec.fProc = pp; 1675140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org } 1676140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org 1677140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org SkXfermode* xfer = NULL; 1678140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org // check if we have a platform optim for that 1679140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org SkProcCoeffXfermode* xfm = SkPlatformXfermodeFactory(rec, mode); 1680140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org if (xfm != NULL) { 1681140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org xfer = xfm; 1682140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org } else { 1683140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org // All modes can in theory be represented by the ProcCoeff rec, since 1684140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org // it contains function ptrs. However, a few modes are both simple and 1685140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org // commonly used, so we call those out for their own subclasses here. 1686140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org switch (mode) { 1687140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org case SkXfermode::kClear_Mode: 1688140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org xfer = SkClearXfermode::Create(rec); 1689140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org break; 1690140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org case SkXfermode::kSrc_Mode: 1691140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org xfer = SkSrcXfermode::Create(rec); 1692140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org break; 1693140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org case SkXfermode::kSrcOver_Mode: 1694140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org SkASSERT(false); // should not land here 1695140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org break; 1696140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org case SkXfermode::kDstIn_Mode: 1697140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org xfer = SkDstInXfermode::Create(rec); 1698140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org break; 1699140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org case SkXfermode::kDstOut_Mode: 1700140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org xfer = SkDstOutXfermode::Create(rec); 1701140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org break; 1702140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org default: 1703140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org // no special-case, just rely in the rec and its function-ptrs 17049fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed xfer = SkNEW_ARGS(SkProcCoeffXfermode, (rec, mode)); 1705140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org break; 1706140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org } 1707140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org } 170897de357270e54be53acb17e1cb4b4d5e25bacc01commit-bot@chromium.org return xfer; 1709140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org} 171097de357270e54be53acb17e1cb4b4d5e25bacc01commit-bot@chromium.org} // namespace 171197de357270e54be53acb17e1cb4b4d5e25bacc01commit-bot@chromium.org 1712140950cc595a3058144681b088e44ff1f8f52d5bcommit-bot@chromium.org 1713a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.comSkXfermode* SkXfermode::Create(Mode mode) { 1714a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount); 17158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 171686490573b5cba554a27637e22485455a7b133de7commit-bot@chromium.org if ((unsigned)mode >= kModeCount) { 171786490573b5cba554a27637e22485455a7b133de7commit-bot@chromium.org // report error 171886490573b5cba554a27637e22485455a7b133de7commit-bot@chromium.org return NULL; 171986490573b5cba554a27637e22485455a7b133de7commit-bot@chromium.org } 1720c0d4aa2088a0788f9df221497945d2ba1b342f44reed@google.com 172197de357270e54be53acb17e1cb4b4d5e25bacc01commit-bot@chromium.org // Skia's "default" mode is srcover. NULL in SkPaint is interpreted as srcover 172286490573b5cba554a27637e22485455a7b133de7commit-bot@chromium.org // so we can just return NULL from the factory. 172386490573b5cba554a27637e22485455a7b133de7commit-bot@chromium.org if (kSrcOver_Mode == mode) { 172486490573b5cba554a27637e22485455a7b133de7commit-bot@chromium.org return NULL; 172586490573b5cba554a27637e22485455a7b133de7commit-bot@chromium.org } 172686490573b5cba554a27637e22485455a7b133de7commit-bot@chromium.org 172797de357270e54be53acb17e1cb4b4d5e25bacc01commit-bot@chromium.org SK_DECLARE_STATIC_LAZY_PTR_ARRAY(SkXfermode, cached, kModeCount, create_mode); 172897de357270e54be53acb17e1cb4b4d5e25bacc01commit-bot@chromium.org return SkSafeRef(cached[mode]); 17298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 173143c50c8c77df82c5cffb55cae2d386e59802b88freed@google.comSkXfermodeProc SkXfermode::GetProc(Mode mode) { 173243c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com SkXfermodeProc proc = NULL; 173343c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com if ((unsigned)mode < kModeCount) { 173443c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com proc = gProcCoeffs[mode].fProc; 173543c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com } 173643c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com return proc; 173743c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com} 173843c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com 173943c50c8c77df82c5cffb55cae2d386e59802b88freed@google.combool SkXfermode::ModeAsCoeff(Mode mode, Coeff* src, Coeff* dst) { 174043c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount); 17411447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 174243c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com if ((unsigned)mode >= (unsigned)kModeCount) { 174343c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com // illegal mode parameter 174443c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com return false; 174543c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com } 17461447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 174743c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com const ProcCoeff& rec = gProcCoeffs[mode]; 17481447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 174943c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com if (CANNOT_USE_COEFF == rec.fSC) { 175043c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com return false; 175143c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com } 17521447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 175343c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com SkASSERT(CANNOT_USE_COEFF != rec.fDC); 175443c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com if (src) { 175543c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com *src = rec.fSC; 175643c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com } 175743c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com if (dst) { 175843c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com *dst = rec.fDC; 175943c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com } 176043c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com return true; 176143c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com} 176243c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com 176330da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.combool SkXfermode::AsMode(const SkXfermode* xfer, Mode* mode) { 17648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == xfer) { 17658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mode) { 17668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *mode = kSrcOver_Mode; 17678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 17688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 17698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1770c0d4aa2088a0788f9df221497945d2ba1b342f44reed@google.com return xfer->asMode(mode); 17718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 177330da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.combool SkXfermode::AsCoeff(const SkXfermode* xfer, Coeff* src, Coeff* dst) { 177443c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com if (NULL == xfer) { 177543c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com return ModeAsCoeff(kSrcOver_Mode, src, dst); 17768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 177743c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com return xfer->asCoeff(src, dst); 17788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 178030da745bbf67a0ee0f305ca7bbdb685cc8a9e686reed@google.combool SkXfermode::IsMode(const SkXfermode* xfer, Mode mode) { 1781e303fcf68d6fee2bf9ee0c4f6fb330a2c3e41a01mike@reedtribe.org // if xfer==null then the mode is srcover 1782e303fcf68d6fee2bf9ee0c4f6fb330a2c3e41a01mike@reedtribe.org Mode m = kSrcOver_Mode; 1783e303fcf68d6fee2bf9ee0c4f6fb330a2c3e41a01mike@reedtribe.org if (xfer && !xfer->asMode(&m)) { 1784e303fcf68d6fee2bf9ee0c4f6fb330a2c3e41a01mike@reedtribe.org return false; 1785e303fcf68d6fee2bf9ee0c4f6fb330a2c3e41a01mike@reedtribe.org } 1786e303fcf68d6fee2bf9ee0c4f6fb330a2c3e41a01mike@reedtribe.org return mode == m; 1787e303fcf68d6fee2bf9ee0c4f6fb330a2c3e41a01mike@reedtribe.org} 1788e303fcf68d6fee2bf9ee0c4f6fb330a2c3e41a01mike@reedtribe.org 17898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 17908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////// 16bit xfermode procs 17918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG 17938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic bool require_255(SkPMColor src) { return SkGetPackedA32(src) == 0xFF; } 17948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic bool require_0(SkPMColor src) { return SkGetPackedA32(src) == 0; } 17958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 17968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic uint16_t src_modeproc16_255(SkPMColor src, uint16_t dst) { 17988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(require_255(src)); 17998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkPixel32ToPixel16(src); 18008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic uint16_t dst_modeproc16(SkPMColor src, uint16_t dst) { 18038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return dst; 18048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic uint16_t srcover_modeproc16_0(SkPMColor src, uint16_t dst) { 18078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(require_0(src)); 18088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return dst; 18098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic uint16_t srcover_modeproc16_255(SkPMColor src, uint16_t dst) { 18128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(require_255(src)); 18138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkPixel32ToPixel16(src); 18148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic uint16_t dstover_modeproc16_0(SkPMColor src, uint16_t dst) { 18178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(require_0(src)); 18188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return dst; 18198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic uint16_t dstover_modeproc16_255(SkPMColor src, uint16_t dst) { 18228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(require_255(src)); 18238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return dst; 18248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic uint16_t srcin_modeproc16_255(SkPMColor src, uint16_t dst) { 18278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(require_255(src)); 18288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkPixel32ToPixel16(src); 18298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic uint16_t dstin_modeproc16_255(SkPMColor src, uint16_t dst) { 18328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(require_255(src)); 18338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return dst; 18348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic uint16_t dstout_modeproc16_0(SkPMColor src, uint16_t dst) { 18378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(require_0(src)); 18388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return dst; 18398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic uint16_t srcatop_modeproc16(SkPMColor src, uint16_t dst) { 18428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned isa = 255 - SkGetPackedA32(src); 18431447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 18448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkPackRGB16( 18458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPacked32ToR16(src) + SkAlphaMulAlpha(SkGetPackedR16(dst), isa), 18468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPacked32ToG16(src) + SkAlphaMulAlpha(SkGetPackedG16(dst), isa), 18478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPacked32ToB16(src) + SkAlphaMulAlpha(SkGetPackedB16(dst), isa)); 18488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic uint16_t srcatop_modeproc16_0(SkPMColor src, uint16_t dst) { 18518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(require_0(src)); 18528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return dst; 18538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic uint16_t srcatop_modeproc16_255(SkPMColor src, uint16_t dst) { 18568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(require_255(src)); 18578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkPixel32ToPixel16(src); 18588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic uint16_t dstatop_modeproc16_255(SkPMColor src, uint16_t dst) { 18618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(require_255(src)); 18628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return dst; 18638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/********* 18668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com darken and lighten boil down to this. 18678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com darken = (1 - Sa) * Dc + min(Sc, Dc) 18698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com lighten = (1 - Sa) * Dc + max(Sc, Dc) 18708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (Sa == 0) these become 18728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com darken = Dc + min(0, Dc) = 0 18738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com lighten = Dc + max(0, Dc) = Dc 18748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (Sa == 1) these become 18768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com darken = min(Sc, Dc) 18778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com lighten = max(Sc, Dc) 18788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 18798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic uint16_t darken_modeproc16_0(SkPMColor src, uint16_t dst) { 18818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(require_0(src)); 18828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return 0; 18838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic uint16_t darken_modeproc16_255(SkPMColor src, uint16_t dst) { 18868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(require_255(src)); 18878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned r = SkFastMin32(SkPacked32ToR16(src), SkGetPackedR16(dst)); 18888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned g = SkFastMin32(SkPacked32ToG16(src), SkGetPackedG16(dst)); 18898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned b = SkFastMin32(SkPacked32ToB16(src), SkGetPackedB16(dst)); 18908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkPackRGB16(r, g, b); 18918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic uint16_t lighten_modeproc16_0(SkPMColor src, uint16_t dst) { 18948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(require_0(src)); 18958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return dst; 18968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic uint16_t lighten_modeproc16_255(SkPMColor src, uint16_t dst) { 18998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(require_255(src)); 19008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned r = SkMax32(SkPacked32ToR16(src), SkGetPackedR16(dst)); 19018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned g = SkMax32(SkPacked32ToG16(src), SkGetPackedG16(dst)); 19028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned b = SkMax32(SkPacked32ToB16(src), SkGetPackedB16(dst)); 19038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkPackRGB16(r, g, b); 19048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 19058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstruct Proc16Rec { 19078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkXfermodeProc16 fProc16_0; 19088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkXfermodeProc16 fProc16_255; 19098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkXfermodeProc16 fProc16_General; 19108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 19118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1912a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.comstatic const Proc16Rec gModeProcs16[] = { 19138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { NULL, NULL, NULL }, // CLEAR 19148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { NULL, src_modeproc16_255, NULL }, 19158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { dst_modeproc16, dst_modeproc16, dst_modeproc16 }, 19168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { srcover_modeproc16_0, srcover_modeproc16_255, NULL }, 19178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { dstover_modeproc16_0, dstover_modeproc16_255, NULL }, 19188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { NULL, srcin_modeproc16_255, NULL }, 19198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { NULL, dstin_modeproc16_255, NULL }, 19208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { NULL, NULL, NULL },// SRC_OUT 19218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { dstout_modeproc16_0, NULL, NULL }, 19228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { srcatop_modeproc16_0, srcatop_modeproc16_255, srcatop_modeproc16 }, 19238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { NULL, dstatop_modeproc16_255, NULL }, 19248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { NULL, NULL, NULL }, // XOR 1925a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com 1926a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com { NULL, NULL, NULL }, // plus 19278d3cd7a170c810e3816bf00220cbef51e7b16795reed@google.com { NULL, NULL, NULL }, // modulate 1928a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com { NULL, NULL, NULL }, // screen 1929a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com { NULL, NULL, NULL }, // overlay 1930a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com { darken_modeproc16_0, darken_modeproc16_255, NULL }, // darken 1931a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com { lighten_modeproc16_0, lighten_modeproc16_255, NULL }, // lighten 1932a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com { NULL, NULL, NULL }, // colordodge 1933a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com { NULL, NULL, NULL }, // colorburn 1934a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com { NULL, NULL, NULL }, // hardlight 1935a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com { NULL, NULL, NULL }, // softlight 1936a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com { NULL, NULL, NULL }, // difference 1937a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com { NULL, NULL, NULL }, // exclusion 1938b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org { NULL, NULL, NULL }, // multiply 1939b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org { NULL, NULL, NULL }, // hue 1940b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org { NULL, NULL, NULL }, // saturation 1941b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org { NULL, NULL, NULL }, // color 1942b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org { NULL, NULL, NULL }, // luminosity 19438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 19448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1945a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.comSkXfermodeProc16 SkXfermode::GetProc16(Mode mode, SkColor srcColor) { 19468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkXfermodeProc16 proc16 = NULL; 1947a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com if ((unsigned)mode < kModeCount) { 1948a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com const Proc16Rec& rec = gModeProcs16[mode]; 19498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned a = SkColorGetA(srcColor); 19508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (0 == a) { 19528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com proc16 = rec.fProc16_0; 19538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else if (255 == a) { 19548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com proc16 = rec.fProc16_255; 19558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 19568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com proc16 = rec.fProc16_General; 19578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 19588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 19598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return proc16; 19608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 19618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1962d26147adbbdca85f07dff432025afee0c8614387caryclark@google.comSK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode) 1963d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode) 1964d26147adbbdca85f07dff432025afee0c8614387caryclark@google.comSK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 1965