1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/include/core/SkMath.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,224 @@ 1.4 + 1.5 +/* 1.6 + * Copyright 2006 The Android Open Source Project 1.7 + * 1.8 + * Use of this source code is governed by a BSD-style license that can be 1.9 + * found in the LICENSE file. 1.10 + */ 1.11 + 1.12 + 1.13 +#ifndef SkMath_DEFINED 1.14 +#define SkMath_DEFINED 1.15 + 1.16 +#include "SkTypes.h" 1.17 + 1.18 +/** 1.19 + * Computes numer1 * numer2 / denom in full 64 intermediate precision. 1.20 + * It is an error for denom to be 0. There is no special handling if 1.21 + * the result overflows 32bits. 1.22 + */ 1.23 +int32_t SkMulDiv(int32_t numer1, int32_t numer2, int32_t denom); 1.24 + 1.25 +/** 1.26 + * Computes (numer1 << shift) / denom in full 64 intermediate precision. 1.27 + * It is an error for denom to be 0. There is no special handling if 1.28 + * the result overflows 32bits. 1.29 + */ 1.30 +int32_t SkDivBits(int32_t numer, int32_t denom, int shift); 1.31 + 1.32 +/** 1.33 + * Return the integer square root of value, with a bias of bitBias 1.34 + */ 1.35 +int32_t SkSqrtBits(int32_t value, int bitBias); 1.36 + 1.37 +/** Return the integer square root of n, treated as a SkFixed (16.16) 1.38 + */ 1.39 +#define SkSqrt32(n) SkSqrtBits(n, 15) 1.40 + 1.41 +// 64bit -> 32bit utilities 1.42 + 1.43 +/** 1.44 + * Return true iff the 64bit value can exactly be represented in signed 32bits 1.45 + */ 1.46 +static inline bool sk_64_isS32(int64_t value) { 1.47 + return (int32_t)value == value; 1.48 +} 1.49 + 1.50 +/** 1.51 + * Return the 64bit argument as signed 32bits, asserting in debug that the arg 1.52 + * exactly fits in signed 32bits. In the release build, no checks are preformed 1.53 + * and the return value if the arg does not fit is undefined. 1.54 + */ 1.55 +static inline int32_t sk_64_asS32(int64_t value) { 1.56 + SkASSERT(sk_64_isS32(value)); 1.57 + return (int32_t)value; 1.58 +} 1.59 + 1.60 +// Handy util that can be passed two ints, and will automatically promote to 1.61 +// 64bits before the multiply, so the caller doesn't have to remember to cast 1.62 +// e.g. (int64_t)a * b; 1.63 +static inline int64_t sk_64_mul(int64_t a, int64_t b) { 1.64 + return a * b; 1.65 +} 1.66 + 1.67 +/////////////////////////////////////////////////////////////////////////////// 1.68 + 1.69 +//! Returns the number of leading zero bits (0...32) 1.70 +int SkCLZ_portable(uint32_t); 1.71 + 1.72 +#ifndef SkCLZ 1.73 + #if defined(_MSC_VER) && _MSC_VER >= 1400 1.74 + #include <intrin.h> 1.75 + 1.76 + static inline int SkCLZ(uint32_t mask) { 1.77 + if (mask) { 1.78 + DWORD index; 1.79 + _BitScanReverse(&index, mask); 1.80 + return index ^ 0x1F; 1.81 + } else { 1.82 + return 32; 1.83 + } 1.84 + } 1.85 + #elif defined(SK_CPU_ARM) || defined(__GNUC__) || defined(__clang__) 1.86 + static inline int SkCLZ(uint32_t mask) { 1.87 + // __builtin_clz(0) is undefined, so we have to detect that case. 1.88 + return mask ? __builtin_clz(mask) : 32; 1.89 + } 1.90 + #else 1.91 + #define SkCLZ(x) SkCLZ_portable(x) 1.92 + #endif 1.93 +#endif 1.94 + 1.95 +/** 1.96 + * Returns (value < 0 ? 0 : value) efficiently (i.e. no compares or branches) 1.97 + */ 1.98 +static inline int SkClampPos(int value) { 1.99 + return value & ~(value >> 31); 1.100 +} 1.101 + 1.102 +/** Given an integer and a positive (max) integer, return the value 1.103 + * pinned against 0 and max, inclusive. 1.104 + * @param value The value we want returned pinned between [0...max] 1.105 + * @param max The positive max value 1.106 + * @return 0 if value < 0, max if value > max, else value 1.107 + */ 1.108 +static inline int SkClampMax(int value, int max) { 1.109 + // ensure that max is positive 1.110 + SkASSERT(max >= 0); 1.111 + if (value < 0) { 1.112 + value = 0; 1.113 + } 1.114 + if (value > max) { 1.115 + value = max; 1.116 + } 1.117 + return value; 1.118 +} 1.119 + 1.120 +/** 1.121 + * Returns the smallest power-of-2 that is >= the specified value. If value 1.122 + * is already a power of 2, then it is returned unchanged. It is undefined 1.123 + * if value is <= 0. 1.124 + */ 1.125 +static inline int SkNextPow2(int value) { 1.126 + SkASSERT(value > 0); 1.127 + return 1 << (32 - SkCLZ(value - 1)); 1.128 +} 1.129 + 1.130 +/** 1.131 + * Returns the log2 of the specified value, were that value to be rounded up 1.132 + * to the next power of 2. It is undefined to pass 0. Examples: 1.133 + * SkNextLog2(1) -> 0 1.134 + * SkNextLog2(2) -> 1 1.135 + * SkNextLog2(3) -> 2 1.136 + * SkNextLog2(4) -> 2 1.137 + * SkNextLog2(5) -> 3 1.138 + */ 1.139 +static inline int SkNextLog2(uint32_t value) { 1.140 + SkASSERT(value != 0); 1.141 + return 32 - SkCLZ(value - 1); 1.142 +} 1.143 + 1.144 +/** 1.145 + * Returns true if value is a power of 2. Does not explicitly check for 1.146 + * value <= 0. 1.147 + */ 1.148 +static inline bool SkIsPow2(int value) { 1.149 + return (value & (value - 1)) == 0; 1.150 +} 1.151 + 1.152 +/////////////////////////////////////////////////////////////////////////////// 1.153 + 1.154 +/** 1.155 + * SkMulS16(a, b) multiplies a * b, but requires that a and b are both int16_t. 1.156 + * With this requirement, we can generate faster instructions on some 1.157 + * architectures. 1.158 + */ 1.159 +#ifdef SK_ARM_HAS_EDSP 1.160 + static inline int32_t SkMulS16(S16CPU x, S16CPU y) { 1.161 + SkASSERT((int16_t)x == x); 1.162 + SkASSERT((int16_t)y == y); 1.163 + int32_t product; 1.164 + asm("smulbb %0, %1, %2 \n" 1.165 + : "=r"(product) 1.166 + : "r"(x), "r"(y) 1.167 + ); 1.168 + return product; 1.169 + } 1.170 +#else 1.171 + #ifdef SK_DEBUG 1.172 + static inline int32_t SkMulS16(S16CPU x, S16CPU y) { 1.173 + SkASSERT((int16_t)x == x); 1.174 + SkASSERT((int16_t)y == y); 1.175 + return x * y; 1.176 + } 1.177 + #else 1.178 + #define SkMulS16(x, y) ((x) * (y)) 1.179 + #endif 1.180 +#endif 1.181 + 1.182 +/** 1.183 + * Return a*b/((1 << shift) - 1), rounding any fractional bits. 1.184 + * Only valid if a and b are unsigned and <= 32767 and shift is > 0 and <= 8 1.185 + */ 1.186 +static inline unsigned SkMul16ShiftRound(U16CPU a, U16CPU b, int shift) { 1.187 + SkASSERT(a <= 32767); 1.188 + SkASSERT(b <= 32767); 1.189 + SkASSERT(shift > 0 && shift <= 8); 1.190 + unsigned prod = SkMulS16(a, b) + (1 << (shift - 1)); 1.191 + return (prod + (prod >> shift)) >> shift; 1.192 +} 1.193 + 1.194 +/** 1.195 + * Return a*b/255, rounding any fractional bits. 1.196 + * Only valid if a and b are unsigned and <= 32767. 1.197 + */ 1.198 +static inline U8CPU SkMulDiv255Round(U16CPU a, U16CPU b) { 1.199 + SkASSERT(a <= 32767); 1.200 + SkASSERT(b <= 32767); 1.201 + unsigned prod = SkMulS16(a, b) + 128; 1.202 + return (prod + (prod >> 8)) >> 8; 1.203 +} 1.204 + 1.205 +/** 1.206 + * Stores numer/denom and numer%denom into div and mod respectively. 1.207 + */ 1.208 +template <typename In, typename Out> 1.209 +inline void SkTDivMod(In numer, In denom, Out* div, Out* mod) { 1.210 +#ifdef SK_CPU_ARM 1.211 + // If we wrote this as in the else branch, GCC won't fuse the two into one 1.212 + // divmod call, but rather a div call followed by a divmod. Silly! This 1.213 + // version is just as fast as calling __aeabi_[u]idivmod manually, but with 1.214 + // prettier code. 1.215 + // 1.216 + // This benches as around 2x faster than the code in the else branch. 1.217 + const In d = numer/denom; 1.218 + *div = static_cast<Out>(d); 1.219 + *mod = static_cast<Out>(numer-d*denom); 1.220 +#else 1.221 + // On x86 this will just be a single idiv. 1.222 + *div = static_cast<Out>(numer/denom); 1.223 + *mod = static_cast<Out>(numer%denom); 1.224 +#endif // SK_CPU_ARM 1.225 +} 1.226 + 1.227 +#endif