aboutsummaryrefslogtreecommitdiffhomepage
path: root/include/core/SkTypes.h
diff options
context:
space:
mode:
authorGravatar mtklein <mtklein@chromium.org>2016-09-26 10:31:12 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-09-26 10:31:12 -0700
commite1a5f4e292384046678edc5c1e360b3e13dc118c (patch)
tree15f6e79d89eb108bf4f39353f5bd5b4508818828 /include/core/SkTypes.h
parent3948a1bf18c246225f6aa11006e94bb3d396eb62 (diff)
My take on SkAlign changes.
Like the other change, it makes SkAlignN(x) macros work for pointers, and makes the macros themselves just syntax sugar for SkAlign<N>(x). We can still decide if we want to sed away the macros independently. This just does it in a somewhat less repetitive way, and adds some tests. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2368293002 No public API changes. TBR=reed@google.com Review-Url: https://codereview.chromium.org/2368293002
Diffstat (limited to 'include/core/SkTypes.h')
-rw-r--r--include/core/SkTypes.h45
1 files changed, 35 insertions, 10 deletions
diff --git a/include/core/SkTypes.h b/include/core/SkTypes.h
index 0cef8a1257..94650f01dc 100644
--- a/include/core/SkTypes.h
+++ b/include/core/SkTypes.h
@@ -332,20 +332,45 @@ template <typename T, size_t N> char (&SkArrayCountHelper(T (&array)[N]))[N];
#define SK_END_REQUIRE_DENSE
#endif
-#define SkAlign2(x) (((x) + 1) >> 1 << 1)
-#define SkIsAlign2(x) (0 == ((x) & 1))
+template <int N, typename T>
+struct SkAlign_traits {
+ static_assert (N > 0 && (N & (N-1)) == 0, "N must be a positive power of 2.");
+ constexpr static int Lg(int k) { return (k == 1) ? 0 : 1 + Lg(k/2); }
-#define SkAlign4(x) (((x) + 3) >> 2 << 2)
-#define SkIsAlign4(x) (0 == ((x) & 3))
+ constexpr static T Align(T x) { return (x + N-1) >> Lg(N) << Lg(N); }
+ constexpr static bool IsAligned(T x) { return 0 == (x & (N-1)); }
+};
+
+template <int N, typename P>
+struct SkAlign_traits<N, P*> {
+ constexpr static P* Align(P* p) {
+ return (P*)SkAlign_traits<N, uintptr_t>::Align((uintptr_t)p);
+ }
+ constexpr static bool IsAligned(P* p) {
+ return SkAlign_traits<N, uintptr_t>::IsAligned((uintptr_t)p);
+ }
+};
+
+template <int N, typename T>
+constexpr static inline T SkAlign(T x) { return SkAlign_traits<N,T>::Align(x); }
+
+template <int N, typename T>
+constexpr static bool SkIsAligned(T x) { return SkAlign_traits<N,T>::IsAligned(x); }
+
+#define SkAlign2(x) SkAlign<2>(x)
+#define SkIsAlign2(x) SkIsAligned<2>(x)
+
+#define SkAlign4(x) SkAlign<4>(x)
+#define SkIsAlign4(x) SkIsAligned<4>(x)
-#define SkAlign8(x) (((x) + 7) >> 3 << 3)
-#define SkIsAlign8(x) (0 == ((x) & 7))
+#define SkAlign8(x) SkAlign<8>(x)
+#define SkIsAlign8(x) SkIsAligned<8>(x)
-#define SkAlign16(x) (((x) + 15) >> 4 << 4)
-#define SkIsAlign16(x) (0 == ((x) & 15))
+#define SkAlign16(x) SkAlign<16>(x)
+#define SkIsAlign16(x) SkIsAligned<16>(x)
-#define SkAlignPtr(x) (sizeof(void*) == 8 ? SkAlign8(x) : SkAlign4(x))
-#define SkIsAlignPtr(x) (sizeof(void*) == 8 ? SkIsAlign8(x) : SkIsAlign4(x))
+#define SkAlignPtr(x) SkAlign<sizeof(void*)>(x)
+#define SkIsAlignPtr(x) SkIsAligned<sizeof(void*)>(x)
typedef uint32_t SkFourByteTag;
#define SkSetFourByteTag(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))