diff options
Diffstat (limited to 'src/core/SkMathPriv.h')
-rw-r--r-- | src/core/SkMathPriv.h | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/src/core/SkMathPriv.h b/src/core/SkMathPriv.h index 1b64a6cd33..fca09f3ffc 100644 --- a/src/core/SkMathPriv.h +++ b/src/core/SkMathPriv.h @@ -92,4 +92,70 @@ static inline float SkPinToUnitFloat(float x) { static inline uint32_t SkBSwap32(uint32_t v) { return __builtin_bswap32(v); } #endif +//! Returns the number of leading zero bits (0...32) +int SkCLZ_portable(uint32_t); + +#ifndef SkCLZ + #if defined(SK_BUILD_FOR_WIN32) + #include <intrin.h> + + static inline int SkCLZ(uint32_t mask) { + if (mask) { + unsigned long index; + _BitScanReverse(&index, mask); + // Suppress this bogus /analyze warning. The check for non-zero + // guarantees that _BitScanReverse will succeed. +#pragma warning(suppress : 6102) // Using 'index' from failed function call + return index ^ 0x1F; + } else { + return 32; + } + } + #elif defined(SK_CPU_ARM32) || defined(__GNUC__) || defined(__clang__) + static inline int SkCLZ(uint32_t mask) { + // __builtin_clz(0) is undefined, so we have to detect that case. + return mask ? __builtin_clz(mask) : 32; + } + #else + #define SkCLZ(x) SkCLZ_portable(x) + #endif +#endif + +/** + * Returns the smallest power-of-2 that is >= the specified value. If value + * is already a power of 2, then it is returned unchanged. It is undefined + * if value is <= 0. + */ +static inline int SkNextPow2(int value) { + SkASSERT(value > 0); + return 1 << (32 - SkCLZ(value - 1)); +} + +/** + * Returns the log2 of the specified value, were that value to be rounded up + * to the next power of 2. It is undefined to pass 0. Examples: + * SkNextLog2(1) -> 0 + * SkNextLog2(2) -> 1 + * SkNextLog2(3) -> 2 + * SkNextLog2(4) -> 2 + * SkNextLog2(5) -> 3 + */ +static inline int SkNextLog2(uint32_t value) { + SkASSERT(value != 0); + return 32 - SkCLZ(value - 1); +} + +/////////////////////////////////////////////////////////////////////////////// + +/** + * Return the next power of 2 >= n. + */ +static inline uint32_t GrNextPow2(uint32_t n) { + return n ? (1 << (32 - SkCLZ(n - 1))) : 1; +} + +static inline int GrNextPow2(int n) { + SkASSERT(n >= 0); // this impl only works for non-neg. + return n ? (1 << (32 - SkCLZ(n - 1))) : 1; +} #endif |