diff options
author | 2016-09-26 10:31:12 -0700 | |
---|---|---|
committer | 2016-09-26 10:31:12 -0700 | |
commit | e1a5f4e292384046678edc5c1e360b3e13dc118c (patch) | |
tree | 15f6e79d89eb108bf4f39353f5bd5b4508818828 /include/core | |
parent | 3948a1bf18c246225f6aa11006e94bb3d396eb62 (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')
-rw-r--r-- | include/core/SkTypes.h | 45 |
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)) |