aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkMathPriv.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/SkMathPriv.h')
-rw-r--r--src/core/SkMathPriv.h66
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