1 /* 2 * Copyright 2006 The Android Open Source Project 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef SkUtils_DEFINED 9 #define SkUtils_DEFINED 10 11 #include "SkTypes.h" 12 13 /////////////////////////////////////////////////////////////////////////////// 14 15 // Determined empirically using bench/MemsetBench.cpp on a Nexus 7, Nexus 9, and desktop. 16 #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2 || defined(SK_ARM_HAS_NEON) 17 // Platforms where we can assume an autovectorizer will give us a good inline memset. 18 #define SK_SMALL_MEMSET 1000 19 #else 20 // Platforms like Chrome on ARMv7 that don't typically compile with NEON globally. 21 #define SK_SMALL_MEMSET 10 22 #endif 23 24 25 /** Similar to memset(), but it assigns a 16bit value into the buffer. 26 @param buffer The memory to have value copied into it 27 @param value The 16bit value to be copied into buffer 28 @param count The number of times value should be copied into the buffer. 29 */ 30 void sk_memset16_large(uint16_t dst[], uint16_t value, int count); 31 inline void sk_memset16(uint16_t dst[], uint16_t value, int count) { 32 if (count <= SK_SMALL_MEMSET) { 33 for (int i = 0; i < count; i++) { 34 dst[i] = value; 35 } 36 } else { 37 sk_memset16_large(dst, value, count); 38 } 39 } 40 typedef void (*SkMemset16Proc)(uint16_t dst[], uint16_t value, int count); 41 SkMemset16Proc SkMemset16GetPlatformProc(); 42 43 /** Similar to memset(), but it assigns a 32bit value into the buffer. 44 @param buffer The memory to have value copied into it 45 @param value The 32bit value to be copied into buffer 46 @param count The number of times value should be copied into the buffer. 47 */ 48 void sk_memset32_large(uint32_t dst[], uint32_t value, int count); 49 inline void sk_memset32(uint32_t dst[], uint32_t value, int count) { 50 if (count <= SK_SMALL_MEMSET) { 51 for (int i = 0; i < count; i++) { 52 dst[i] = value; 53 } 54 } else { 55 sk_memset32_large(dst, value, count); 56 } 57 } 58 59 typedef void (*SkMemset32Proc)(uint32_t dst[], uint32_t value, int count); 60 SkMemset32Proc SkMemset32GetPlatformProc(); 61 62 #undef SK_SMALL_MEMSET 63 64 /** Similar to memcpy(), but it copies count 32bit values from src to dst. 65 @param dst The memory to have value copied into it 66 @param src The memory to have value copied from it 67 @param count The number of values should be copied. 68 */ 69 void sk_memcpy32(uint32_t dst[], const uint32_t src[], int count); 70 typedef void (*SkMemcpy32Proc)(uint32_t dst[], const uint32_t src[], int count); 71 SkMemcpy32Proc SkMemcpy32GetPlatformProc(); 72 73 /////////////////////////////////////////////////////////////////////////////// 74 75 #define kMaxBytesInUTF8Sequence 4 76 77 #ifdef SK_DEBUG 78 int SkUTF8_LeadByteToCount(unsigned c); 79 #else 80 #define SkUTF8_LeadByteToCount(c) ((((0xE5 << 24) >> ((unsigned)c >> 4 << 1)) & 3) + 1) 81 #endif 82 83 inline int SkUTF8_CountUTF8Bytes(const char utf8[]) { 84 SkASSERT(utf8); 85 return SkUTF8_LeadByteToCount(*(const uint8_t*)utf8); 86 } 87 88 int SkUTF8_CountUnichars(const char utf8[]); 89 int SkUTF8_CountUnichars(const char utf8[], size_t byteLength); 90 SkUnichar SkUTF8_ToUnichar(const char utf8[]); 91 SkUnichar SkUTF8_NextUnichar(const char**); 92 SkUnichar SkUTF8_PrevUnichar(const char**); 93 94 /** Return the number of bytes need to convert a unichar 95 into a utf8 sequence. Will be 1..kMaxBytesInUTF8Sequence, 96 or 0 if uni is illegal. 97 */ 98 size_t SkUTF8_FromUnichar(SkUnichar uni, char utf8[] = NULL); 99 100 /////////////////////////////////////////////////////////////////////////////// 101 102 #define SkUTF16_IsHighSurrogate(c) (((c) & 0xFC00) == 0xD800) 103 #define SkUTF16_IsLowSurrogate(c) (((c) & 0xFC00) == 0xDC00) 104 105 int SkUTF16_CountUnichars(const uint16_t utf16[]); 106 int SkUTF16_CountUnichars(const uint16_t utf16[], int numberOf16BitValues); 107 // returns the current unichar and then moves past it (*p++) 108 SkUnichar SkUTF16_NextUnichar(const uint16_t**); 109 // this guy backs up to the previus unichar value, and returns it (*--p) 110 SkUnichar SkUTF16_PrevUnichar(const uint16_t**); 111 size_t SkUTF16_FromUnichar(SkUnichar uni, uint16_t utf16[] = NULL); 112 113 size_t SkUTF16_ToUTF8(const uint16_t utf16[], int numberOf16BitValues, 114 char utf8[] = NULL); 115 116 inline bool SkUnichar_IsVariationSelector(SkUnichar uni) { 117 /* The 'true' ranges are: 118 * 0x180B <= uni <= 0x180D 119 * 0xFE00 <= uni <= 0xFE0F 120 * 0xE0100 <= uni <= 0xE01EF 121 */ 122 if (uni < 0x180B || uni > 0xE01EF) { 123 return false; 124 } 125 if ((uni > 0x180D && uni < 0xFE00) || (uni > 0xFE0F && uni < 0xE0100)) { 126 return false; 127 } 128 return true; 129 } 130 131 /////////////////////////////////////////////////////////////////////////////// 132 133 class SkAutoTrace { 134 public: 135 /** NOTE: label contents are not copied, just the ptr is 136 retained, so DON'T DELETE IT. 137 */ 138 SkAutoTrace(const char label[]) : fLabel(label) { 139 SkDebugf("--- trace: %s Enter\n", fLabel); 140 } 141 ~SkAutoTrace() { 142 SkDebugf("--- trace: %s Leave\n", fLabel); 143 } 144 private: 145 const char* fLabel; 146 }; 147 #define SkAutoTrace(...) SK_REQUIRE_LOCAL_VAR(SkAutoTrace) 148 149 #endif 150