OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 The Android Open Source Project |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 | 9 |
10 #include "SkUtils.h" | 10 #include "SkUtils.h" |
11 #include "SkLazyFnPtr.h" | |
12 | |
13 #if 0 | |
14 #define assign_16_longs(dst, value) \ | |
15 do { \ | |
16 (dst)[0] = value; (dst)[1] = value; \ | |
17 (dst)[2] = value; (dst)[3] = value; \ | |
18 (dst)[4] = value; (dst)[5] = value; \ | |
19 (dst)[6] = value; (dst)[7] = value; \ | |
20 (dst)[8] = value; (dst)[9] = value; \ | |
21 (dst)[10] = value; (dst)[11] = value; \ | |
22 (dst)[12] = value; (dst)[13] = value; \ | |
23 (dst)[14] = value; (dst)[15] = value; \ | |
24 } while (0) | |
25 #else | |
26 #define assign_16_longs(dst, value) \ | |
27 do { \ | |
28 *(dst)++ = value; *(dst)++ = value; \ | |
29 *(dst)++ = value; *(dst)++ = value; \ | |
30 *(dst)++ = value; *(dst)++ = value; \ | |
31 *(dst)++ = value; *(dst)++ = value; \ | |
32 *(dst)++ = value; *(dst)++ = value; \ | |
33 *(dst)++ = value; *(dst)++ = value; \ | |
34 *(dst)++ = value; *(dst)++ = value; \ | |
35 *(dst)++ = value; *(dst)++ = value; \ | |
36 } while (0) | |
37 #endif | |
38 | |
39 /////////////////////////////////////////////////////////////////////////////// | |
40 | |
41 static void sk_memset16_portable(uint16_t dst[], uint16_t value, int count) { | |
42 SkASSERT(dst != NULL && count >= 0); | |
43 | |
44 if (count <= 0) { | |
45 return; | |
46 } | |
47 | |
48 // not sure if this helps to short-circuit on small values of count | |
49 if (count < 8) { | |
50 do { | |
51 *dst++ = (uint16_t)value; | |
52 } while (--count != 0); | |
53 return; | |
54 } | |
55 | |
56 // ensure we're on a long boundary | |
57 if ((size_t)dst & 2) { | |
58 *dst++ = (uint16_t)value; | |
59 count -= 1; | |
60 } | |
61 | |
62 uint32_t value32 = ((uint32_t)value << 16) | value; | |
63 | |
64 // handle the bulk with our unrolled macro | |
65 { | |
66 int sixteenlongs = count >> 5; | |
67 if (sixteenlongs) { | |
68 uint32_t* dst32 = (uint32_t*)dst; | |
69 do { | |
70 assign_16_longs(dst32, value32); | |
71 } while (--sixteenlongs != 0); | |
72 dst = (uint16_t*)dst32; | |
73 count &= 31; | |
74 } | |
75 } | |
76 | |
77 // handle (most) of the rest | |
78 { | |
79 int longs = count >> 1; | |
80 if (longs) { | |
81 do { | |
82 *(uint32_t*)dst = value32; | |
83 dst += 2; | |
84 } while (--longs != 0); | |
85 } | |
86 } | |
87 | |
88 // cleanup a possible trailing short | |
89 if (count & 1) { | |
90 *dst = (uint16_t)value; | |
91 } | |
92 } | |
93 | |
94 static void sk_memset32_portable(uint32_t dst[], uint32_t value, int count) { | |
95 SkASSERT(dst != NULL && count >= 0); | |
96 | |
97 int sixteenlongs = count >> 4; | |
98 if (sixteenlongs) { | |
99 do { | |
100 assign_16_longs(dst, value); | |
101 } while (--sixteenlongs != 0); | |
102 count &= 15; | |
103 } | |
104 | |
105 if (count) { | |
106 do { | |
107 *dst++ = value; | |
108 } while (--count != 0); | |
109 } | |
110 } | |
111 | |
112 namespace { | |
113 // These three methods technically need external linkage to be passed as templat
e parameters. | |
114 // Since they can't be static, we hide them in an anonymous namespace instead. | |
115 | |
116 SkMemset16Proc choose_memset16() { | |
117 SkMemset16Proc proc = SkMemset16GetPlatformProc(); | |
118 return proc ? proc : sk_memset16_portable; | |
119 } | |
120 | |
121 SkMemset32Proc choose_memset32() { | |
122 SkMemset32Proc proc = SkMemset32GetPlatformProc(); | |
123 return proc ? proc : sk_memset32_portable; | |
124 } | |
125 | |
126 } // namespace | |
127 | |
128 void sk_memset16_large(uint16_t dst[], uint16_t value, int count) { | |
129 SK_DECLARE_STATIC_LAZY_FN_PTR(SkMemset16Proc, proc, choose_memset16); | |
130 proc.get()(dst, value, count); | |
131 } | |
132 | |
133 void sk_memset32_large(uint32_t dst[], uint32_t value, int count) { | |
134 SK_DECLARE_STATIC_LAZY_FN_PTR(SkMemset32Proc, proc, choose_memset32); | |
135 proc.get()(dst, value, count); | |
136 } | |
137 | |
138 /////////////////////////////////////////////////////////////////////////////// | |
139 | 11 |
140 /* 0xxxxxxx 1 total | 12 /* 0xxxxxxx 1 total |
141 10xxxxxx // never a leading byte | 13 10xxxxxx // never a leading byte |
142 110xxxxx 2 total | 14 110xxxxx 2 total |
143 1110xxxx 3 total | 15 1110xxxx 3 total |
144 11110xxx 4 total | 16 11110xxx 4 total |
145 | 17 |
146 11 10 01 01 xx xx xx xx 0... | 18 11 10 01 01 xx xx xx xx 0... |
147 0xE5XX0000 | 19 0xE5XX0000 |
148 0xE5 << 24 | 20 0xE5 << 24 |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
399 } | 271 } |
400 } else { | 272 } else { |
401 char* start = utf8; | 273 char* start = utf8; |
402 while (utf16 < stop) { | 274 while (utf16 < stop) { |
403 utf8 += SkUTF8_FromUnichar(SkUTF16_NextUnichar(&utf16), utf8); | 275 utf8 += SkUTF8_FromUnichar(SkUTF16_NextUnichar(&utf16), utf8); |
404 } | 276 } |
405 size = utf8 - start; | 277 size = utf8 - start; |
406 } | 278 } |
407 return size; | 279 return size; |
408 } | 280 } |
OLD | NEW |