10060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org#ifndef SkColor_opts_neon_DEFINED 20060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org#define SkColor_opts_neon_DEFINED 30060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org 40060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org#include "SkTypes.h" 5d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com#include "SkColorPriv.h" 60060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org 7cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org#include <arm_neon.h> 8cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org 90060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org#define NEON_A (SK_A32_SHIFT / 8) 100060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org#define NEON_R (SK_R32_SHIFT / 8) 110060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org#define NEON_G (SK_G32_SHIFT / 8) 120060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org#define NEON_B (SK_B32_SHIFT / 8) 130060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org 14cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.orgstatic inline uint16x8_t SkAlpha255To256_neon8(uint8x8_t alpha) { 15cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org return vaddw_u8(vdupq_n_u16(1), alpha); 16cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org} 17cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org 18cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.orgstatic inline uint8x8_t SkAlphaMul_neon8(uint8x8_t color, uint16x8_t scale) { 19cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org return vshrn_n_u16(vmovl_u8(color) * scale, 8); 20cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org} 21cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org 22cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.orgstatic inline uint8x8x4_t SkAlphaMulQ_neon8(uint8x8x4_t color, uint16x8_t scale) { 23cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org uint8x8x4_t ret; 24cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org 25cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org ret.val[NEON_A] = SkAlphaMul_neon8(color.val[NEON_A], scale); 26cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org ret.val[NEON_R] = SkAlphaMul_neon8(color.val[NEON_R], scale); 27cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org ret.val[NEON_G] = SkAlphaMul_neon8(color.val[NEON_G], scale); 28cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org ret.val[NEON_B] = SkAlphaMul_neon8(color.val[NEON_B], scale); 29cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org 30cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org return ret; 31cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org} 32cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org 33bc25dfc798fff225ce65355ecda19d2b85bd0e74commit-bot@chromium.org/* This function expands 8 pixels from RGB565 (R, G, B from high to low) to 34bc25dfc798fff225ce65355ecda19d2b85bd0e74commit-bot@chromium.org * SkPMColor (all possible configurations supported) in the exact same way as 35bc25dfc798fff225ce65355ecda19d2b85bd0e74commit-bot@chromium.org * SkPixel16ToPixel32. 36bc25dfc798fff225ce65355ecda19d2b85bd0e74commit-bot@chromium.org */ 37bc25dfc798fff225ce65355ecda19d2b85bd0e74commit-bot@chromium.orgstatic inline uint8x8x4_t SkPixel16ToPixel32_neon8(uint16x8_t vsrc) { 38bc25dfc798fff225ce65355ecda19d2b85bd0e74commit-bot@chromium.org 39bc25dfc798fff225ce65355ecda19d2b85bd0e74commit-bot@chromium.org uint8x8x4_t ret; 40bc25dfc798fff225ce65355ecda19d2b85bd0e74commit-bot@chromium.org uint8x8_t vr, vg, vb; 41bc25dfc798fff225ce65355ecda19d2b85bd0e74commit-bot@chromium.org 42bc25dfc798fff225ce65355ecda19d2b85bd0e74commit-bot@chromium.org vr = vmovn_u16(vshrq_n_u16(vsrc, SK_R16_SHIFT)); 43bc25dfc798fff225ce65355ecda19d2b85bd0e74commit-bot@chromium.org vg = vmovn_u16(vshrq_n_u16(vshlq_n_u16(vsrc, SK_R16_BITS), SK_R16_BITS + SK_B16_BITS)); 44bc25dfc798fff225ce65355ecda19d2b85bd0e74commit-bot@chromium.org vb = vmovn_u16(vsrc & vdupq_n_u16(SK_B16_MASK)); 45bc25dfc798fff225ce65355ecda19d2b85bd0e74commit-bot@chromium.org 46bc25dfc798fff225ce65355ecda19d2b85bd0e74commit-bot@chromium.org ret.val[NEON_A] = vdup_n_u8(0xFF); 47bc25dfc798fff225ce65355ecda19d2b85bd0e74commit-bot@chromium.org ret.val[NEON_R] = vshl_n_u8(vr, 8 - SK_R16_BITS) | vshr_n_u8(vr, 2 * SK_R16_BITS - 8); 48bc25dfc798fff225ce65355ecda19d2b85bd0e74commit-bot@chromium.org ret.val[NEON_G] = vshl_n_u8(vg, 8 - SK_G16_BITS) | vshr_n_u8(vg, 2 * SK_G16_BITS - 8); 49bc25dfc798fff225ce65355ecda19d2b85bd0e74commit-bot@chromium.org ret.val[NEON_B] = vshl_n_u8(vb, 8 - SK_B16_BITS) | vshr_n_u8(vb, 2 * SK_B16_BITS - 8); 50bc25dfc798fff225ce65355ecda19d2b85bd0e74commit-bot@chromium.org 51bc25dfc798fff225ce65355ecda19d2b85bd0e74commit-bot@chromium.org return ret; 52bc25dfc798fff225ce65355ecda19d2b85bd0e74commit-bot@chromium.org} 53bc25dfc798fff225ce65355ecda19d2b85bd0e74commit-bot@chromium.org 54bc25dfc798fff225ce65355ecda19d2b85bd0e74commit-bot@chromium.org/* This function packs 8 pixels from SkPMColor (all possible configurations 55bc25dfc798fff225ce65355ecda19d2b85bd0e74commit-bot@chromium.org * supported) to RGB565 (R, G, B from high to low) in the exact same way as 56bc25dfc798fff225ce65355ecda19d2b85bd0e74commit-bot@chromium.org * SkPixel32ToPixel16. 57bc25dfc798fff225ce65355ecda19d2b85bd0e74commit-bot@chromium.org */ 58bc25dfc798fff225ce65355ecda19d2b85bd0e74commit-bot@chromium.orgstatic inline uint16x8_t SkPixel32ToPixel16_neon8(uint8x8x4_t vsrc) { 59bc25dfc798fff225ce65355ecda19d2b85bd0e74commit-bot@chromium.org 60bc25dfc798fff225ce65355ecda19d2b85bd0e74commit-bot@chromium.org uint16x8_t ret; 61bc25dfc798fff225ce65355ecda19d2b85bd0e74commit-bot@chromium.org 62bc25dfc798fff225ce65355ecda19d2b85bd0e74commit-bot@chromium.org ret = vshll_n_u8(vsrc.val[NEON_R], 8); 63bc25dfc798fff225ce65355ecda19d2b85bd0e74commit-bot@chromium.org ret = vsriq_n_u16(ret, vshll_n_u8(vsrc.val[NEON_G], 8), SK_R16_BITS); 64bc25dfc798fff225ce65355ecda19d2b85bd0e74commit-bot@chromium.org ret = vsriq_n_u16(ret, vshll_n_u8(vsrc.val[NEON_B], 8), SK_R16_BITS + SK_G16_BITS); 65bc25dfc798fff225ce65355ecda19d2b85bd0e74commit-bot@chromium.org 66bc25dfc798fff225ce65355ecda19d2b85bd0e74commit-bot@chromium.org return ret; 67bc25dfc798fff225ce65355ecda19d2b85bd0e74commit-bot@chromium.org} 68bc25dfc798fff225ce65355ecda19d2b85bd0e74commit-bot@chromium.org 69d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com/* This function blends 8 pixels of the same channel in the exact same way as 70d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com * SkBlend32. 71d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com */ 72d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.comstatic inline uint8x8_t SkBlend32_neon8(uint8x8_t src, uint8x8_t dst, uint16x8_t scale) { 73d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com int16x8_t src_wide, dst_wide; 74d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com 75d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com src_wide = vreinterpretq_s16_u16(vmovl_u8(src)); 76d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com dst_wide = vreinterpretq_s16_u16(vmovl_u8(dst)); 77d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com 78d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com src_wide = (src_wide - dst_wide) * vreinterpretq_s16_u16(scale); 79d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com 80d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com dst_wide += vshrq_n_s16(src_wide, 5); 81d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com 82d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com return vmovn_u16(vreinterpretq_u16_s16(dst_wide)); 83d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com} 84d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com 8546e266cdbe6da0a4553ec0004bcc7f9524829c9ecommit-bot@chromium.orgstatic inline SkPMColor SkFourByteInterp256_neon(SkPMColor src, SkPMColor dst, 8646e266cdbe6da0a4553ec0004bcc7f9524829c9ecommit-bot@chromium.org unsigned srcScale) { 8746e266cdbe6da0a4553ec0004bcc7f9524829c9ecommit-bot@chromium.org SkASSERT(srcScale <= 256); 8846e266cdbe6da0a4553ec0004bcc7f9524829c9ecommit-bot@chromium.org int16x8_t vscale = vdupq_n_s16(srcScale); 8946e266cdbe6da0a4553ec0004bcc7f9524829c9ecommit-bot@chromium.org int16x8_t vsrc_wide, vdst_wide, vdiff; 9046e266cdbe6da0a4553ec0004bcc7f9524829c9ecommit-bot@chromium.org uint8x8_t res; 9146e266cdbe6da0a4553ec0004bcc7f9524829c9ecommit-bot@chromium.org 9246e266cdbe6da0a4553ec0004bcc7f9524829c9ecommit-bot@chromium.org vsrc_wide = vreinterpretq_s16_u16(vmovl_u8(vreinterpret_u8_u32(vdup_n_u32(src)))); 9346e266cdbe6da0a4553ec0004bcc7f9524829c9ecommit-bot@chromium.org vdst_wide = vreinterpretq_s16_u16(vmovl_u8(vreinterpret_u8_u32(vdup_n_u32(dst)))); 9446e266cdbe6da0a4553ec0004bcc7f9524829c9ecommit-bot@chromium.org 9546e266cdbe6da0a4553ec0004bcc7f9524829c9ecommit-bot@chromium.org vdiff = vsrc_wide - vdst_wide; 9646e266cdbe6da0a4553ec0004bcc7f9524829c9ecommit-bot@chromium.org vdiff *= vscale; 9746e266cdbe6da0a4553ec0004bcc7f9524829c9ecommit-bot@chromium.org 9846e266cdbe6da0a4553ec0004bcc7f9524829c9ecommit-bot@chromium.org vdiff = vshrq_n_s16(vdiff, 8); 9946e266cdbe6da0a4553ec0004bcc7f9524829c9ecommit-bot@chromium.org 10046e266cdbe6da0a4553ec0004bcc7f9524829c9ecommit-bot@chromium.org vdst_wide += vdiff; 10146e266cdbe6da0a4553ec0004bcc7f9524829c9ecommit-bot@chromium.org 10246e266cdbe6da0a4553ec0004bcc7f9524829c9ecommit-bot@chromium.org res = vmovn_u16(vreinterpretq_u16_s16(vdst_wide)); 10346e266cdbe6da0a4553ec0004bcc7f9524829c9ecommit-bot@chromium.org 10446e266cdbe6da0a4553ec0004bcc7f9524829c9ecommit-bot@chromium.org return vget_lane_u32(vreinterpret_u32_u8(res), 0); 10546e266cdbe6da0a4553ec0004bcc7f9524829c9ecommit-bot@chromium.org} 10646e266cdbe6da0a4553ec0004bcc7f9524829c9ecommit-bot@chromium.org 10746e266cdbe6da0a4553ec0004bcc7f9524829c9ecommit-bot@chromium.orgstatic inline SkPMColor SkFourByteInterp_neon(SkPMColor src, SkPMColor dst, 10846e266cdbe6da0a4553ec0004bcc7f9524829c9ecommit-bot@chromium.org U8CPU srcWeight) { 10946e266cdbe6da0a4553ec0004bcc7f9524829c9ecommit-bot@chromium.org SkASSERT(srcWeight <= 255); 11046e266cdbe6da0a4553ec0004bcc7f9524829c9ecommit-bot@chromium.org unsigned scale = SkAlpha255To256(srcWeight); 11146e266cdbe6da0a4553ec0004bcc7f9524829c9ecommit-bot@chromium.org return SkFourByteInterp256_neon(src, dst, scale); 11246e266cdbe6da0a4553ec0004bcc7f9524829c9ecommit-bot@chromium.org} 11346e266cdbe6da0a4553ec0004bcc7f9524829c9ecommit-bot@chromium.org 1140060159457453ca45a47828648c8f29d5695983ccommit-bot@chromium.org#endif /* #ifndef SkColor_opts_neon_DEFINED */ 115