OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkBlitMask.h" | 8 #include "SkBlitMask.h" |
9 #include "SkColor_opts_neon.h" | 9 #include "SkColor_opts_neon.h" |
10 | 10 |
11 static void D32_A8_Black_neon(void* SK_RESTRICT dst, size_t dstRB, | |
12 const void* SK_RESTRICT maskPtr, size_t maskRB, | |
13 SkColor, int width, int height) { | |
14 SkPMColor* SK_RESTRICT device = (SkPMColor*)dst; | |
15 const uint8_t* SK_RESTRICT mask = (const uint8_t*)maskPtr; | |
16 | |
17 maskRB -= width; | |
18 dstRB -= (width << 2); | |
19 do { | |
20 int w = width; | |
21 while (w >= 8) { | |
22 uint8x8_t vmask = vld1_u8(mask); | |
23 uint16x8_t vscale = vsubw_u8(vdupq_n_u16(256), vmask); | |
24 uint8x8x4_t vdevice = vld4_u8((uint8_t*)device); | |
25 | |
26 vdevice = SkAlphaMulQ_neon8(vdevice, vscale); | |
27 vdevice.val[NEON_A] += vmask; | |
28 | |
29 vst4_u8((uint8_t*)device, vdevice); | |
30 | |
31 mask += 8; | |
32 device += 8; | |
33 w -= 8; | |
34 } | |
35 while (w-- > 0) { | |
36 unsigned aa = *mask++; | |
37 *device = (aa << SK_A32_SHIFT) | |
38 + SkAlphaMulQ(*device, SkAlpha255To256(255 - aa)); | |
39 device += 1; | |
40 }; | |
41 device = (uint32_t*)((char*)device + dstRB); | |
42 mask += maskRB; | |
43 } while (--height != 0); | |
44 } | |
45 | |
46 template <bool isColor> | |
47 static void D32_A8_Opaque_Color_neon(void* SK_RESTRICT dst, size_t dstRB, | |
48 const void* SK_RESTRICT maskPtr, size_t mas
kRB, | |
49 SkColor color, int width, int height) { | |
50 SkPMColor pmc = SkPreMultiplyColor(color); | |
51 SkPMColor* SK_RESTRICT device = (SkPMColor*)dst; | |
52 const uint8_t* SK_RESTRICT mask = (const uint8_t*)maskPtr; | |
53 uint8x8x4_t vpmc; | |
54 | |
55 maskRB -= width; | |
56 dstRB -= (width << 2); | |
57 | |
58 if (width >= 8) { | |
59 vpmc.val[NEON_A] = vdup_n_u8(SkGetPackedA32(pmc)); | |
60 vpmc.val[NEON_R] = vdup_n_u8(SkGetPackedR32(pmc)); | |
61 vpmc.val[NEON_G] = vdup_n_u8(SkGetPackedG32(pmc)); | |
62 vpmc.val[NEON_B] = vdup_n_u8(SkGetPackedB32(pmc)); | |
63 } | |
64 do { | |
65 int w = width; | |
66 while (w >= 8) { | |
67 uint8x8_t vmask = vld1_u8(mask); | |
68 uint16x8_t vscale, vmask256 = SkAlpha255To256_neon8(vmask); | |
69 if (isColor) { | |
70 vscale = vsubw_u8(vdupq_n_u16(256), | |
71 SkAlphaMul_neon8(vpmc.val[NEON_A], vmask256)); | |
72 } else { | |
73 vscale = vsubw_u8(vdupq_n_u16(256), vmask); | |
74 } | |
75 uint8x8x4_t vdev = vld4_u8((uint8_t*)device); | |
76 | |
77 vdev.val[NEON_A] = SkAlphaMul_neon8(vpmc.val[NEON_A], vmask256) | |
78 + SkAlphaMul_neon8(vdev.val[NEON_A], vscale); | |
79 vdev.val[NEON_R] = SkAlphaMul_neon8(vpmc.val[NEON_R], vmask256) | |
80 + SkAlphaMul_neon8(vdev.val[NEON_R], vscale); | |
81 vdev.val[NEON_G] = SkAlphaMul_neon8(vpmc.val[NEON_G], vmask256) | |
82 + SkAlphaMul_neon8(vdev.val[NEON_G], vscale); | |
83 vdev.val[NEON_B] = SkAlphaMul_neon8(vpmc.val[NEON_B], vmask256) | |
84 + SkAlphaMul_neon8(vdev.val[NEON_B], vscale); | |
85 | |
86 vst4_u8((uint8_t*)device, vdev); | |
87 | |
88 mask += 8; | |
89 device += 8; | |
90 w -= 8; | |
91 } | |
92 | |
93 while (w--) { | |
94 unsigned aa = *mask++; | |
95 if (isColor) { | |
96 *device = SkBlendARGB32(pmc, *device, aa); | |
97 } else { | |
98 *device = SkAlphaMulQ(pmc, SkAlpha255To256(aa)) | |
99 + SkAlphaMulQ(*device, SkAlpha255To256(255 - aa)); | |
100 } | |
101 device += 1; | |
102 }; | |
103 | |
104 device = (uint32_t*)((char*)device + dstRB); | |
105 mask += maskRB; | |
106 | |
107 } while (--height != 0); | |
108 } | |
109 | |
110 static void D32_A8_Opaque_neon(void* SK_RESTRICT dst, size_t dstRB, | |
111 const void* SK_RESTRICT maskPtr, size_t maskRB, | |
112 SkColor color, int width, int height) { | |
113 D32_A8_Opaque_Color_neon<false>(dst, dstRB, maskPtr, maskRB, color, width, h
eight); | |
114 } | |
115 | |
116 static void D32_A8_Color_neon(void* SK_RESTRICT dst, size_t dstRB, | |
117 const void* SK_RESTRICT maskPtr, size_t maskRB, | |
118 SkColor color, int width, int height) { | |
119 D32_A8_Opaque_Color_neon<true>(dst, dstRB, maskPtr, maskRB, color, width, he
ight); | |
120 } | |
121 | |
122 SkBlitMask::ColorProc D32_A8_Factory_neon(SkColor color) { | |
123 if (SK_ColorBLACK == color) { | |
124 return D32_A8_Black_neon; | |
125 } else if (0xFF == SkColorGetA(color)) { | |
126 return D32_A8_Opaque_neon; | |
127 } else { | |
128 return D32_A8_Color_neon; | |
129 } | |
130 } | |
131 | |
132 //////////////////////////////////////////////////////////////////////////////// | |
133 | |
134 void SkBlitLCD16OpaqueRow_neon(SkPMColor dst[], const uint16_t src[], | 11 void SkBlitLCD16OpaqueRow_neon(SkPMColor dst[], const uint16_t src[], |
135 SkColor color, int width, | 12 SkColor color, int width, |
136 SkPMColor opaqueDst) { | 13 SkPMColor opaqueDst) { |
137 int colR = SkColorGetR(color); | 14 int colR = SkColorGetR(color); |
138 int colG = SkColorGetG(color); | 15 int colG = SkColorGetG(color); |
139 int colB = SkColorGetB(color); | 16 int colB = SkColorGetB(color); |
140 | 17 |
141 uint8x8_t vcolR, vcolG, vcolB; | 18 uint8x8_t vcolR, vcolG, vcolB; |
142 uint8x8_t vopqDstA, vopqDstR, vopqDstG, vopqDstB; | 19 uint8x8_t vopqDstA, vopqDstR, vopqDstG, vopqDstB; |
143 | 20 |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 while (height != 0){ | 202 while (height != 0){ |
326 uint32_t dst32 = SkExpand_rgb_16(*device) * scale; | 203 uint32_t dst32 = SkExpand_rgb_16(*device) * scale; |
327 *device = SkCompact_rgb_16((src32 + dst32) >> 5); | 204 *device = SkCompact_rgb_16((src32 + dst32) >> 5); |
328 device = (uint16_t*)((char*)device + deviceRB); | 205 device = (uint16_t*)((char*)device + deviceRB); |
329 height--; | 206 height--; |
330 } | 207 } |
331 } | 208 } |
332 | 209 |
333 #undef LOAD_LANE_16 | 210 #undef LOAD_LANE_16 |
334 #undef STORE_LANE_16 | 211 #undef STORE_LANE_16 |
OLD | NEW |