1/* 2 * Copyright 2012 Google Inc. 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 SkMathPriv_DEFINED 9#define SkMathPriv_DEFINED 10 11#include "include/core/SkMath.h" 12 13/** 14 * Return the integer square root of value, with a bias of bitBias 15 */ 16int32_t SkSqrtBits(int32_t value, int bitBias); 17 18/** Return the integer square root of n, treated as a SkFixed (16.16) 19 */ 20static inline int32_t SkSqrt32(int32_t n) { return SkSqrtBits(n, 15); } 21 22/** 23 * Returns (value < 0 ? 0 : value) efficiently (i.e. no compares or branches) 24 */ 25static inline int SkClampPos(int value) { 26 return value & ~(value >> 31); 27} 28 29/** 30 * Stores numer/denom and numer%denom into div and mod respectively. 31 */ 32template <typename In, typename Out> 33inline void SkTDivMod(In numer, In denom, Out* div, Out* mod) { 34#ifdef SK_CPU_ARM32 35 // If we wrote this as in the else branch, GCC won't fuse the two into one 36 // divmod call, but rather a div call followed by a divmod. Silly! This 37 // version is just as fast as calling __aeabi_[u]idivmod manually, but with 38 // prettier code. 39 // 40 // This benches as around 2x faster than the code in the else branch. 41 const In d = numer/denom; 42 *div = static_cast<Out>(d); 43 *mod = static_cast<Out>(numer-d*denom); 44#else 45 // On x86 this will just be a single idiv. 46 *div = static_cast<Out>(numer/denom); 47 *mod = static_cast<Out>(numer%denom); 48#endif 49} 50 51/** Returns -1 if n < 0, else returns 0 52 */ 53#define SkExtractSign(n) ((int32_t)(n) >> 31) 54 55/** If sign == -1, returns -n, else sign must be 0, and returns n. 56 Typically used in conjunction with SkExtractSign(). 57 */ 58static inline int32_t SkApplySign(int32_t n, int32_t sign) { 59 SkASSERT(sign == 0 || sign == -1); 60 return (n ^ sign) - sign; 61} 62 63/** Return x with the sign of y */ 64static inline int32_t SkCopySign32(int32_t x, int32_t y) { 65 return SkApplySign(x, SkExtractSign(x ^ y)); 66} 67 68/** Given a positive value and a positive max, return the value 69 pinned against max. 70 Note: only works as long as max - value doesn't wrap around 71 @return max if value >= max, else value 72 */ 73static inline unsigned SkClampUMax(unsigned value, unsigned max) { 74 if (value > max) { 75 value = max; 76 } 77 return value; 78} 79 80// If a signed int holds min_int (e.g. 0x80000000) it is undefined what happens when 81// we negate it (even though we *know* we're 2's complement and we'll get the same 82// value back). So we create this helper function that casts to size_t (unsigned) first, 83// to avoid the complaint. 84static inline size_t sk_negate_to_size_t(int32_t value) { 85#if defined(_MSC_VER) 86#pragma warning(push) 87#pragma warning(disable : 4146) // Thanks MSVC, we know what we're negating an unsigned 88#endif 89 return -static_cast<size_t>(value); 90#if defined(_MSC_VER) 91#pragma warning(pop) 92#endif 93} 94 95/////////////////////////////////////////////////////////////////////////////// 96 97/** Return a*b/255, truncating away any fractional bits. Only valid if both 98 a and b are 0..255 99 */ 100static inline U8CPU SkMulDiv255Trunc(U8CPU a, U8CPU b) { 101 SkASSERT((uint8_t)a == a); 102 SkASSERT((uint8_t)b == b); 103 unsigned prod = a*b + 1; 104 return (prod + (prod >> 8)) >> 8; 105} 106 107/** Return (a*b)/255, taking the ceiling of any fractional bits. Only valid if 108 both a and b are 0..255. The expected result equals (a * b + 254) / 255. 109 */ 110static inline U8CPU SkMulDiv255Ceiling(U8CPU a, U8CPU b) { 111 SkASSERT((uint8_t)a == a); 112 SkASSERT((uint8_t)b == b); 113 unsigned prod = a*b + 255; 114 return (prod + (prod >> 8)) >> 8; 115} 116 117/** Just the rounding step in SkDiv255Round: round(value / 255) 118 */ 119static inline unsigned SkDiv255Round(unsigned prod) { 120 prod += 128; 121 return (prod + (prod >> 8)) >> 8; 122} 123 124/** 125 * Swap byte order of a 4-byte value, e.g. 0xaarrggbb -> 0xbbggrraa. 126 */ 127#if defined(_MSC_VER) 128 #include <stdlib.h> 129 static inline uint32_t SkBSwap32(uint32_t v) { return _byteswap_ulong(v); } 130#else 131 static inline uint32_t SkBSwap32(uint32_t v) { return __builtin_bswap32(v); } 132#endif 133 134//! Returns the number of leading zero bits (0...32) 135// From Hacker's Delight 2nd Edition 136constexpr int SkCLZ_portable(uint32_t x) { 137 int n = 32; 138 uint32_t y = x >> 16; if (y != 0) {n -= 16; x = y;} 139 y = x >> 8; if (y != 0) {n -= 8; x = y;} 140 y = x >> 4; if (y != 0) {n -= 4; x = y;} 141 y = x >> 2; if (y != 0) {n -= 2; x = y;} 142 y = x >> 1; if (y != 0) {return n - 2;} 143 return n - x; 144} 145 146static_assert(32 == SkCLZ_portable(0)); 147static_assert(31 == SkCLZ_portable(1)); 148static_assert( 1 == SkCLZ_portable(1 << 30)); 149static_assert( 1 == SkCLZ_portable((1 << 30) | (1 << 24) | 1)); 150static_assert( 0 == SkCLZ_portable(~0U)); 151 152#if defined(SK_BUILD_FOR_WIN) 153 #include <intrin.h> 154 155 static inline int SkCLZ(uint32_t mask) { 156 if (mask) { 157 unsigned long index = 0; 158 _BitScanReverse(&index, mask); 159 // Suppress this bogus /analyze warning. The check for non-zero 160 // guarantees that _BitScanReverse will succeed. 161 // #pragma warning(suppress : 6102) // Using 'index' from failed function call 162 return index ^ 0x1F; 163 } else { 164 return 32; 165 } 166 } 167#elif defined(SK_CPU_ARM32) || defined(__GNUC__) || defined(__clang__) 168 static inline int SkCLZ(uint32_t mask) { 169 // __builtin_clz(0) is undefined, so we have to detect that case. 170 return mask ? __builtin_clz(mask) : 32; 171 } 172#else 173 static inline int SkCLZ(uint32_t mask) { 174 return SkCLZ_portable(mask); 175 } 176#endif 177 178//! Returns the number of trailing zero bits (0...32) 179// From Hacker's Delight 2nd Edition 180constexpr int SkCTZ_portable(uint32_t x) { 181 return 32 - SkCLZ_portable(~x & (x - 1)); 182} 183 184static_assert(32 == SkCTZ_portable(0)); 185static_assert( 0 == SkCTZ_portable(1)); 186static_assert(30 == SkCTZ_portable(1 << 30)); 187static_assert( 2 == SkCTZ_portable((1 << 30) | (1 << 24) | (1 << 2))); 188static_assert( 0 == SkCTZ_portable(~0U)); 189 190#if defined(SK_BUILD_FOR_WIN) 191 #include <intrin.h> 192 193 static inline int SkCTZ(uint32_t mask) { 194 if (mask) { 195 unsigned long index = 0; 196 _BitScanForward(&index, mask); 197 // Suppress this bogus /analyze warning. The check for non-zero 198 // guarantees that _BitScanReverse will succeed. 199 // #pragma warning(suppress : 6102) // Using 'index' from failed function call 200 return index; 201 } else { 202 return 32; 203 } 204 } 205#elif defined(SK_CPU_ARM32) || defined(__GNUC__) || defined(__clang__) 206 static inline int SkCTZ(uint32_t mask) { 207 // __builtin_ctz(0) is undefined, so we have to detect that case. 208 return mask ? __builtin_ctz(mask) : 32; 209 } 210#else 211 static inline int SkCTZ(uint32_t mask) { 212 return SkCTZ_portable(mask); 213 } 214#endif 215 216/** 217 * Returns the log2 of the specified value, were that value to be rounded up 218 * to the next power of 2. It is undefined to pass 0. Examples: 219 * SkNextLog2(1) -> 0 220 * SkNextLog2(2) -> 1 221 * SkNextLog2(3) -> 2 222 * SkNextLog2(4) -> 2 223 * SkNextLog2(5) -> 3 224 */ 225static inline int SkNextLog2(uint32_t value) { 226 SkASSERT(value != 0); 227 return 32 - SkCLZ(value - 1); 228} 229 230constexpr int SkNextLog2_portable(uint32_t value) { 231 SkASSERT(value != 0); 232 return 32 - SkCLZ_portable(value - 1); 233} 234 235/** 236* Returns the log2 of the specified value, were that value to be rounded down 237* to the previous power of 2. It is undefined to pass 0. Examples: 238* SkPrevLog2(1) -> 0 239* SkPrevLog2(2) -> 1 240* SkPrevLog2(3) -> 1 241* SkPrevLog2(4) -> 2 242* SkPrevLog2(5) -> 2 243*/ 244static inline int SkPrevLog2(uint32_t value) { 245 SkASSERT(value != 0); 246 return 32 - SkCLZ(value >> 1); 247} 248 249constexpr int SkPrevLog2_portable(uint32_t value) { 250 SkASSERT(value != 0); 251 return 32 - SkCLZ_portable(value >> 1); 252} 253 254/** 255 * Returns the smallest power-of-2 that is >= the specified value. If value 256 * is already a power of 2, then it is returned unchanged. It is undefined 257 * if value is <= 0. 258 */ 259static inline int SkNextPow2(int value) { 260 SkASSERT(value > 0); 261 return 1 << SkNextLog2(value); 262} 263 264constexpr int SkNextPow2_portable(int value) { 265 SkASSERT(value > 0); 266 return 1 << SkNextLog2_portable(value); 267} 268 269/** 270* Returns the largest power-of-2 that is <= the specified value. If value 271* is already a power of 2, then it is returned unchanged. It is undefined 272* if value is <= 0. 273*/ 274static inline int SkPrevPow2(int value) { 275 SkASSERT(value > 0); 276 return 1 << SkPrevLog2(value); 277} 278 279constexpr int SkPrevPow2_portable(int value) { 280 SkASSERT(value > 0); 281 return 1 << SkPrevLog2_portable(value); 282} 283 284/////////////////////////////////////////////////////////////////////////////// 285 286/** 287 * Return the smallest power-of-2 >= n. 288 */ 289static inline uint32_t GrNextPow2(uint32_t n) { 290 return n ? (1 << (32 - SkCLZ(n - 1))) : 1; 291} 292 293/** 294 * Returns the next power of 2 >= n or n if the next power of 2 can't be represented by size_t. 295 */ 296static inline size_t GrNextSizePow2(size_t n) { 297 constexpr int kNumSizeTBits = 8 * sizeof(size_t); 298 constexpr size_t kHighBitSet = size_t(1) << (kNumSizeTBits - 1); 299 300 if (!n) { 301 return 1; 302 } else if (n >= kHighBitSet) { 303 return n; 304 } 305 306 n--; 307 uint32_t shift = 1; 308 while (shift < kNumSizeTBits) { 309 n |= n >> shift; 310 shift <<= 1; 311 } 312 return n + 1; 313} 314 315// conservative check. will return false for very large values that "could" fit 316template <typename T> static inline bool SkFitsInFixed(T x) { 317 return SkTAbs(x) <= 32767.0f; 318} 319 320#endif 321