| 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 |