1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2012 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker *
4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker */
7*c8dee2aaSAndroid Build Coastguard Worker
8*c8dee2aaSAndroid Build Coastguard Worker #ifndef SkMathPriv_DEFINED
9*c8dee2aaSAndroid Build Coastguard Worker #define SkMathPriv_DEFINED
10*c8dee2aaSAndroid Build Coastguard Worker
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkAssert.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkCPUTypes.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTemplates.h"
14*c8dee2aaSAndroid Build Coastguard Worker
15*c8dee2aaSAndroid Build Coastguard Worker #include <cstddef>
16*c8dee2aaSAndroid Build Coastguard Worker #include <cstdint>
17*c8dee2aaSAndroid Build Coastguard Worker
18*c8dee2aaSAndroid Build Coastguard Worker /**
19*c8dee2aaSAndroid Build Coastguard Worker * Return the integer square root of value, with a bias of bitBias
20*c8dee2aaSAndroid Build Coastguard Worker */
21*c8dee2aaSAndroid Build Coastguard Worker int32_t SkSqrtBits(int32_t value, int bitBias);
22*c8dee2aaSAndroid Build Coastguard Worker
23*c8dee2aaSAndroid Build Coastguard Worker /** Return the integer square root of n, treated as a SkFixed (16.16)
24*c8dee2aaSAndroid Build Coastguard Worker */
SkSqrt32(int32_t n)25*c8dee2aaSAndroid Build Coastguard Worker static inline int32_t SkSqrt32(int32_t n) { return SkSqrtBits(n, 15); }
26*c8dee2aaSAndroid Build Coastguard Worker
27*c8dee2aaSAndroid Build Coastguard Worker /**
28*c8dee2aaSAndroid Build Coastguard Worker * Returns (value < 0 ? 0 : value) efficiently (i.e. no compares or branches)
29*c8dee2aaSAndroid Build Coastguard Worker */
SkClampPos(int value)30*c8dee2aaSAndroid Build Coastguard Worker static inline int SkClampPos(int value) {
31*c8dee2aaSAndroid Build Coastguard Worker return value & ~(value >> 31);
32*c8dee2aaSAndroid Build Coastguard Worker }
33*c8dee2aaSAndroid Build Coastguard Worker
34*c8dee2aaSAndroid Build Coastguard Worker /**
35*c8dee2aaSAndroid Build Coastguard Worker * Stores numer/denom and numer%denom into div and mod respectively.
36*c8dee2aaSAndroid Build Coastguard Worker */
37*c8dee2aaSAndroid Build Coastguard Worker template <typename In, typename Out>
SkTDivMod(In numer,In denom,Out * div,Out * mod)38*c8dee2aaSAndroid Build Coastguard Worker inline void SkTDivMod(In numer, In denom, Out* div, Out* mod) {
39*c8dee2aaSAndroid Build Coastguard Worker *div = static_cast<Out>(numer/denom);
40*c8dee2aaSAndroid Build Coastguard Worker *mod = static_cast<Out>(numer%denom);
41*c8dee2aaSAndroid Build Coastguard Worker }
42*c8dee2aaSAndroid Build Coastguard Worker
43*c8dee2aaSAndroid Build Coastguard Worker /** Returns -1 if n < 0, else returns 0
44*c8dee2aaSAndroid Build Coastguard Worker */
45*c8dee2aaSAndroid Build Coastguard Worker #define SkExtractSign(n) ((int32_t)(n) >> 31)
46*c8dee2aaSAndroid Build Coastguard Worker
47*c8dee2aaSAndroid Build Coastguard Worker /** If sign == -1, returns -n, else sign must be 0, and returns n.
48*c8dee2aaSAndroid Build Coastguard Worker Typically used in conjunction with SkExtractSign().
49*c8dee2aaSAndroid Build Coastguard Worker */
SkApplySign(int32_t n,int32_t sign)50*c8dee2aaSAndroid Build Coastguard Worker static inline int32_t SkApplySign(int32_t n, int32_t sign) {
51*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(sign == 0 || sign == -1);
52*c8dee2aaSAndroid Build Coastguard Worker return (n ^ sign) - sign;
53*c8dee2aaSAndroid Build Coastguard Worker }
54*c8dee2aaSAndroid Build Coastguard Worker
55*c8dee2aaSAndroid Build Coastguard Worker /** Return x with the sign of y */
SkCopySign32(int32_t x,int32_t y)56*c8dee2aaSAndroid Build Coastguard Worker static inline int32_t SkCopySign32(int32_t x, int32_t y) {
57*c8dee2aaSAndroid Build Coastguard Worker return SkApplySign(x, SkExtractSign(x ^ y));
58*c8dee2aaSAndroid Build Coastguard Worker }
59*c8dee2aaSAndroid Build Coastguard Worker
60*c8dee2aaSAndroid Build Coastguard Worker /** Given a positive value and a positive max, return the value
61*c8dee2aaSAndroid Build Coastguard Worker pinned against max.
62*c8dee2aaSAndroid Build Coastguard Worker Note: only works as long as max - value doesn't wrap around
63*c8dee2aaSAndroid Build Coastguard Worker @return max if value >= max, else value
64*c8dee2aaSAndroid Build Coastguard Worker */
SkClampUMax(unsigned value,unsigned max)65*c8dee2aaSAndroid Build Coastguard Worker static inline unsigned SkClampUMax(unsigned value, unsigned max) {
66*c8dee2aaSAndroid Build Coastguard Worker if (value > max) {
67*c8dee2aaSAndroid Build Coastguard Worker value = max;
68*c8dee2aaSAndroid Build Coastguard Worker }
69*c8dee2aaSAndroid Build Coastguard Worker return value;
70*c8dee2aaSAndroid Build Coastguard Worker }
71*c8dee2aaSAndroid Build Coastguard Worker
72*c8dee2aaSAndroid Build Coastguard Worker // If a signed int holds min_int (e.g. 0x80000000) it is undefined what happens when
73*c8dee2aaSAndroid Build Coastguard Worker // we negate it (even though we *know* we're 2's complement and we'll get the same
74*c8dee2aaSAndroid Build Coastguard Worker // value back). So we create this helper function that casts to size_t (unsigned) first,
75*c8dee2aaSAndroid Build Coastguard Worker // to avoid the complaint.
sk_negate_to_size_t(int32_t value)76*c8dee2aaSAndroid Build Coastguard Worker static inline size_t sk_negate_to_size_t(int32_t value) {
77*c8dee2aaSAndroid Build Coastguard Worker #if defined(_MSC_VER)
78*c8dee2aaSAndroid Build Coastguard Worker #pragma warning(push)
79*c8dee2aaSAndroid Build Coastguard Worker #pragma warning(disable : 4146) // Thanks MSVC, we know what we're negating an unsigned
80*c8dee2aaSAndroid Build Coastguard Worker #endif
81*c8dee2aaSAndroid Build Coastguard Worker return -static_cast<size_t>(value);
82*c8dee2aaSAndroid Build Coastguard Worker #if defined(_MSC_VER)
83*c8dee2aaSAndroid Build Coastguard Worker #pragma warning(pop)
84*c8dee2aaSAndroid Build Coastguard Worker #endif
85*c8dee2aaSAndroid Build Coastguard Worker }
86*c8dee2aaSAndroid Build Coastguard Worker
87*c8dee2aaSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
88*c8dee2aaSAndroid Build Coastguard Worker
89*c8dee2aaSAndroid Build Coastguard Worker /** Return a*b/255, truncating away any fractional bits. Only valid if both
90*c8dee2aaSAndroid Build Coastguard Worker a and b are 0..255
91*c8dee2aaSAndroid Build Coastguard Worker */
SkMulDiv255Trunc(U8CPU a,U8CPU b)92*c8dee2aaSAndroid Build Coastguard Worker static inline U8CPU SkMulDiv255Trunc(U8CPU a, U8CPU b) {
93*c8dee2aaSAndroid Build Coastguard Worker SkASSERT((uint8_t)a == a);
94*c8dee2aaSAndroid Build Coastguard Worker SkASSERT((uint8_t)b == b);
95*c8dee2aaSAndroid Build Coastguard Worker unsigned prod = a*b + 1;
96*c8dee2aaSAndroid Build Coastguard Worker return (prod + (prod >> 8)) >> 8;
97*c8dee2aaSAndroid Build Coastguard Worker }
98*c8dee2aaSAndroid Build Coastguard Worker
99*c8dee2aaSAndroid Build Coastguard Worker /** Return (a*b)/255, taking the ceiling of any fractional bits. Only valid if
100*c8dee2aaSAndroid Build Coastguard Worker both a and b are 0..255. The expected result equals (a * b + 254) / 255.
101*c8dee2aaSAndroid Build Coastguard Worker */
SkMulDiv255Ceiling(U8CPU a,U8CPU b)102*c8dee2aaSAndroid Build Coastguard Worker static inline U8CPU SkMulDiv255Ceiling(U8CPU a, U8CPU b) {
103*c8dee2aaSAndroid Build Coastguard Worker SkASSERT((uint8_t)a == a);
104*c8dee2aaSAndroid Build Coastguard Worker SkASSERT((uint8_t)b == b);
105*c8dee2aaSAndroid Build Coastguard Worker unsigned prod = a*b + 255;
106*c8dee2aaSAndroid Build Coastguard Worker return (prod + (prod >> 8)) >> 8;
107*c8dee2aaSAndroid Build Coastguard Worker }
108*c8dee2aaSAndroid Build Coastguard Worker
109*c8dee2aaSAndroid Build Coastguard Worker /** Just the rounding step in SkDiv255Round: round(value / 255)
110*c8dee2aaSAndroid Build Coastguard Worker */
SkDiv255Round(unsigned prod)111*c8dee2aaSAndroid Build Coastguard Worker static inline unsigned SkDiv255Round(unsigned prod) {
112*c8dee2aaSAndroid Build Coastguard Worker prod += 128;
113*c8dee2aaSAndroid Build Coastguard Worker return (prod + (prod >> 8)) >> 8;
114*c8dee2aaSAndroid Build Coastguard Worker }
115*c8dee2aaSAndroid Build Coastguard Worker
116*c8dee2aaSAndroid Build Coastguard Worker /**
117*c8dee2aaSAndroid Build Coastguard Worker * Swap byte order of a 4-byte value, e.g. 0xaarrggbb -> 0xbbggrraa.
118*c8dee2aaSAndroid Build Coastguard Worker */
119*c8dee2aaSAndroid Build Coastguard Worker #if defined(_MSC_VER)
120*c8dee2aaSAndroid Build Coastguard Worker #include <stdlib.h>
SkBSwap32(uint32_t v)121*c8dee2aaSAndroid Build Coastguard Worker static inline uint32_t SkBSwap32(uint32_t v) { return _byteswap_ulong(v); }
122*c8dee2aaSAndroid Build Coastguard Worker #else
SkBSwap32(uint32_t v)123*c8dee2aaSAndroid Build Coastguard Worker static inline uint32_t SkBSwap32(uint32_t v) { return __builtin_bswap32(v); }
124*c8dee2aaSAndroid Build Coastguard Worker #endif
125*c8dee2aaSAndroid Build Coastguard Worker
126*c8dee2aaSAndroid Build Coastguard Worker /*
127*c8dee2aaSAndroid Build Coastguard Worker * Return the number of set bits (i.e., the population count) in the provided uint32_t.
128*c8dee2aaSAndroid Build Coastguard Worker */
129*c8dee2aaSAndroid Build Coastguard Worker int SkPopCount_portable(uint32_t n);
130*c8dee2aaSAndroid Build Coastguard Worker
131*c8dee2aaSAndroid Build Coastguard Worker #if defined(__GNUC__) || defined(__clang__)
SkPopCount(uint32_t n)132*c8dee2aaSAndroid Build Coastguard Worker static inline int SkPopCount(uint32_t n) {
133*c8dee2aaSAndroid Build Coastguard Worker return __builtin_popcount(n);
134*c8dee2aaSAndroid Build Coastguard Worker }
135*c8dee2aaSAndroid Build Coastguard Worker #else
SkPopCount(uint32_t n)136*c8dee2aaSAndroid Build Coastguard Worker static inline int SkPopCount(uint32_t n) {
137*c8dee2aaSAndroid Build Coastguard Worker return SkPopCount_portable(n);
138*c8dee2aaSAndroid Build Coastguard Worker }
139*c8dee2aaSAndroid Build Coastguard Worker #endif
140*c8dee2aaSAndroid Build Coastguard Worker
141*c8dee2aaSAndroid Build Coastguard Worker /*
142*c8dee2aaSAndroid Build Coastguard Worker * Return the 0-based index of the nth bit set in target
143*c8dee2aaSAndroid Build Coastguard Worker * Returns 32 if there is no nth bit set.
144*c8dee2aaSAndroid Build Coastguard Worker */
145*c8dee2aaSAndroid Build Coastguard Worker int SkNthSet(uint32_t target, int n);
146*c8dee2aaSAndroid Build Coastguard Worker
147*c8dee2aaSAndroid Build Coastguard Worker //! Returns the number of leading zero bits (0...32)
148*c8dee2aaSAndroid Build Coastguard Worker // From Hacker's Delight 2nd Edition
SkCLZ_portable(uint32_t x)149*c8dee2aaSAndroid Build Coastguard Worker constexpr int SkCLZ_portable(uint32_t x) {
150*c8dee2aaSAndroid Build Coastguard Worker int n = 32;
151*c8dee2aaSAndroid Build Coastguard Worker uint32_t y = x >> 16; if (y != 0) {n -= 16; x = y;}
152*c8dee2aaSAndroid Build Coastguard Worker y = x >> 8; if (y != 0) {n -= 8; x = y;}
153*c8dee2aaSAndroid Build Coastguard Worker y = x >> 4; if (y != 0) {n -= 4; x = y;}
154*c8dee2aaSAndroid Build Coastguard Worker y = x >> 2; if (y != 0) {n -= 2; x = y;}
155*c8dee2aaSAndroid Build Coastguard Worker y = x >> 1; if (y != 0) {return n - 2;}
156*c8dee2aaSAndroid Build Coastguard Worker return n - static_cast<int>(x);
157*c8dee2aaSAndroid Build Coastguard Worker }
158*c8dee2aaSAndroid Build Coastguard Worker
159*c8dee2aaSAndroid Build Coastguard Worker static_assert(32 == SkCLZ_portable(0));
160*c8dee2aaSAndroid Build Coastguard Worker static_assert(31 == SkCLZ_portable(1));
161*c8dee2aaSAndroid Build Coastguard Worker static_assert( 1 == SkCLZ_portable(1 << 30));
162*c8dee2aaSAndroid Build Coastguard Worker static_assert( 1 == SkCLZ_portable((1 << 30) | (1 << 24) | 1));
163*c8dee2aaSAndroid Build Coastguard Worker static_assert( 0 == SkCLZ_portable(~0U));
164*c8dee2aaSAndroid Build Coastguard Worker
165*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_BUILD_FOR_WIN)
166*c8dee2aaSAndroid Build Coastguard Worker #include <intrin.h>
167*c8dee2aaSAndroid Build Coastguard Worker
SkCLZ(uint32_t mask)168*c8dee2aaSAndroid Build Coastguard Worker static inline int SkCLZ(uint32_t mask) {
169*c8dee2aaSAndroid Build Coastguard Worker if (mask) {
170*c8dee2aaSAndroid Build Coastguard Worker unsigned long index = 0;
171*c8dee2aaSAndroid Build Coastguard Worker _BitScanReverse(&index, mask);
172*c8dee2aaSAndroid Build Coastguard Worker // Suppress this bogus /analyze warning. The check for non-zero
173*c8dee2aaSAndroid Build Coastguard Worker // guarantees that _BitScanReverse will succeed.
174*c8dee2aaSAndroid Build Coastguard Worker #pragma warning(push)
175*c8dee2aaSAndroid Build Coastguard Worker #pragma warning(suppress : 6102) // Using 'index' from failed function call
176*c8dee2aaSAndroid Build Coastguard Worker return static_cast<int>(index ^ 0x1F);
177*c8dee2aaSAndroid Build Coastguard Worker #pragma warning(pop)
178*c8dee2aaSAndroid Build Coastguard Worker } else {
179*c8dee2aaSAndroid Build Coastguard Worker return 32;
180*c8dee2aaSAndroid Build Coastguard Worker }
181*c8dee2aaSAndroid Build Coastguard Worker }
182*c8dee2aaSAndroid Build Coastguard Worker #elif defined(SK_CPU_ARM32) || defined(__GNUC__) || defined(__clang__)
SkCLZ(uint32_t mask)183*c8dee2aaSAndroid Build Coastguard Worker static inline int SkCLZ(uint32_t mask) {
184*c8dee2aaSAndroid Build Coastguard Worker // __builtin_clz(0) is undefined, so we have to detect that case.
185*c8dee2aaSAndroid Build Coastguard Worker return mask ? __builtin_clz(mask) : 32;
186*c8dee2aaSAndroid Build Coastguard Worker }
187*c8dee2aaSAndroid Build Coastguard Worker #else
SkCLZ(uint32_t mask)188*c8dee2aaSAndroid Build Coastguard Worker static inline int SkCLZ(uint32_t mask) {
189*c8dee2aaSAndroid Build Coastguard Worker return SkCLZ_portable(mask);
190*c8dee2aaSAndroid Build Coastguard Worker }
191*c8dee2aaSAndroid Build Coastguard Worker #endif
192*c8dee2aaSAndroid Build Coastguard Worker
193*c8dee2aaSAndroid Build Coastguard Worker //! Returns the number of trailing zero bits (0...32)
194*c8dee2aaSAndroid Build Coastguard Worker // From Hacker's Delight 2nd Edition
SkCTZ_portable(uint32_t x)195*c8dee2aaSAndroid Build Coastguard Worker constexpr int SkCTZ_portable(uint32_t x) {
196*c8dee2aaSAndroid Build Coastguard Worker return 32 - SkCLZ_portable(~x & (x - 1));
197*c8dee2aaSAndroid Build Coastguard Worker }
198*c8dee2aaSAndroid Build Coastguard Worker
199*c8dee2aaSAndroid Build Coastguard Worker static_assert(32 == SkCTZ_portable(0));
200*c8dee2aaSAndroid Build Coastguard Worker static_assert( 0 == SkCTZ_portable(1));
201*c8dee2aaSAndroid Build Coastguard Worker static_assert(30 == SkCTZ_portable(1 << 30));
202*c8dee2aaSAndroid Build Coastguard Worker static_assert( 2 == SkCTZ_portable((1 << 30) | (1 << 24) | (1 << 2)));
203*c8dee2aaSAndroid Build Coastguard Worker static_assert( 0 == SkCTZ_portable(~0U));
204*c8dee2aaSAndroid Build Coastguard Worker
205*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_BUILD_FOR_WIN)
206*c8dee2aaSAndroid Build Coastguard Worker #include <intrin.h>
207*c8dee2aaSAndroid Build Coastguard Worker
SkCTZ(uint32_t mask)208*c8dee2aaSAndroid Build Coastguard Worker static inline int SkCTZ(uint32_t mask) {
209*c8dee2aaSAndroid Build Coastguard Worker if (mask) {
210*c8dee2aaSAndroid Build Coastguard Worker unsigned long index = 0;
211*c8dee2aaSAndroid Build Coastguard Worker _BitScanForward(&index, mask);
212*c8dee2aaSAndroid Build Coastguard Worker // Suppress this bogus /analyze warning. The check for non-zero
213*c8dee2aaSAndroid Build Coastguard Worker // guarantees that _BitScanReverse will succeed.
214*c8dee2aaSAndroid Build Coastguard Worker #pragma warning(push)
215*c8dee2aaSAndroid Build Coastguard Worker #pragma warning(suppress : 6102) // Using 'index' from failed function call
216*c8dee2aaSAndroid Build Coastguard Worker return static_cast<int>(index);
217*c8dee2aaSAndroid Build Coastguard Worker #pragma warning(pop)
218*c8dee2aaSAndroid Build Coastguard Worker } else {
219*c8dee2aaSAndroid Build Coastguard Worker return 32;
220*c8dee2aaSAndroid Build Coastguard Worker }
221*c8dee2aaSAndroid Build Coastguard Worker }
222*c8dee2aaSAndroid Build Coastguard Worker #elif defined(SK_CPU_ARM32) || defined(__GNUC__) || defined(__clang__)
SkCTZ(uint32_t mask)223*c8dee2aaSAndroid Build Coastguard Worker static inline int SkCTZ(uint32_t mask) {
224*c8dee2aaSAndroid Build Coastguard Worker // __builtin_ctz(0) is undefined, so we have to detect that case.
225*c8dee2aaSAndroid Build Coastguard Worker return mask ? __builtin_ctz(mask) : 32;
226*c8dee2aaSAndroid Build Coastguard Worker }
227*c8dee2aaSAndroid Build Coastguard Worker #else
SkCTZ(uint32_t mask)228*c8dee2aaSAndroid Build Coastguard Worker static inline int SkCTZ(uint32_t mask) {
229*c8dee2aaSAndroid Build Coastguard Worker return SkCTZ_portable(mask);
230*c8dee2aaSAndroid Build Coastguard Worker }
231*c8dee2aaSAndroid Build Coastguard Worker #endif
232*c8dee2aaSAndroid Build Coastguard Worker
233*c8dee2aaSAndroid Build Coastguard Worker /**
234*c8dee2aaSAndroid Build Coastguard Worker * Returns the log2 of the specified value, were that value to be rounded up
235*c8dee2aaSAndroid Build Coastguard Worker * to the next power of 2. It is undefined to pass 0. Examples:
236*c8dee2aaSAndroid Build Coastguard Worker * SkNextLog2(1) -> 0
237*c8dee2aaSAndroid Build Coastguard Worker * SkNextLog2(2) -> 1
238*c8dee2aaSAndroid Build Coastguard Worker * SkNextLog2(3) -> 2
239*c8dee2aaSAndroid Build Coastguard Worker * SkNextLog2(4) -> 2
240*c8dee2aaSAndroid Build Coastguard Worker * SkNextLog2(5) -> 3
241*c8dee2aaSAndroid Build Coastguard Worker */
SkNextLog2(uint32_t value)242*c8dee2aaSAndroid Build Coastguard Worker static inline int SkNextLog2(uint32_t value) {
243*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(value != 0);
244*c8dee2aaSAndroid Build Coastguard Worker return 32 - SkCLZ(value - 1);
245*c8dee2aaSAndroid Build Coastguard Worker }
246*c8dee2aaSAndroid Build Coastguard Worker
SkNextLog2_portable(uint32_t value)247*c8dee2aaSAndroid Build Coastguard Worker constexpr int SkNextLog2_portable(uint32_t value) {
248*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(value != 0);
249*c8dee2aaSAndroid Build Coastguard Worker return 32 - SkCLZ_portable(value - 1);
250*c8dee2aaSAndroid Build Coastguard Worker }
251*c8dee2aaSAndroid Build Coastguard Worker
252*c8dee2aaSAndroid Build Coastguard Worker /**
253*c8dee2aaSAndroid Build Coastguard Worker * Returns the log2 of the specified value, were that value to be rounded down
254*c8dee2aaSAndroid Build Coastguard Worker * to the previous power of 2. It is undefined to pass 0. Examples:
255*c8dee2aaSAndroid Build Coastguard Worker * SkPrevLog2(1) -> 0
256*c8dee2aaSAndroid Build Coastguard Worker * SkPrevLog2(2) -> 1
257*c8dee2aaSAndroid Build Coastguard Worker * SkPrevLog2(3) -> 1
258*c8dee2aaSAndroid Build Coastguard Worker * SkPrevLog2(4) -> 2
259*c8dee2aaSAndroid Build Coastguard Worker * SkPrevLog2(5) -> 2
260*c8dee2aaSAndroid Build Coastguard Worker */
SkPrevLog2(uint32_t value)261*c8dee2aaSAndroid Build Coastguard Worker static inline int SkPrevLog2(uint32_t value) {
262*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(value != 0);
263*c8dee2aaSAndroid Build Coastguard Worker return 32 - SkCLZ(value >> 1);
264*c8dee2aaSAndroid Build Coastguard Worker }
265*c8dee2aaSAndroid Build Coastguard Worker
SkPrevLog2_portable(uint32_t value)266*c8dee2aaSAndroid Build Coastguard Worker constexpr int SkPrevLog2_portable(uint32_t value) {
267*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(value != 0);
268*c8dee2aaSAndroid Build Coastguard Worker return 32 - SkCLZ_portable(value >> 1);
269*c8dee2aaSAndroid Build Coastguard Worker }
270*c8dee2aaSAndroid Build Coastguard Worker
271*c8dee2aaSAndroid Build Coastguard Worker /**
272*c8dee2aaSAndroid Build Coastguard Worker * Returns the smallest power-of-2 that is >= the specified value. If value
273*c8dee2aaSAndroid Build Coastguard Worker * is already a power of 2, then it is returned unchanged. It is undefined
274*c8dee2aaSAndroid Build Coastguard Worker * if value is <= 0.
275*c8dee2aaSAndroid Build Coastguard Worker */
SkNextPow2(int value)276*c8dee2aaSAndroid Build Coastguard Worker static inline int SkNextPow2(int value) {
277*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(value > 0);
278*c8dee2aaSAndroid Build Coastguard Worker return 1 << SkNextLog2(static_cast<uint32_t>(value));
279*c8dee2aaSAndroid Build Coastguard Worker }
280*c8dee2aaSAndroid Build Coastguard Worker
SkNextPow2_portable(int value)281*c8dee2aaSAndroid Build Coastguard Worker constexpr int SkNextPow2_portable(int value) {
282*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(value > 0);
283*c8dee2aaSAndroid Build Coastguard Worker return 1 << SkNextLog2_portable(static_cast<uint32_t>(value));
284*c8dee2aaSAndroid Build Coastguard Worker }
285*c8dee2aaSAndroid Build Coastguard Worker
286*c8dee2aaSAndroid Build Coastguard Worker /**
287*c8dee2aaSAndroid Build Coastguard Worker * Returns the largest power-of-2 that is <= the specified value. If value
288*c8dee2aaSAndroid Build Coastguard Worker * is already a power of 2, then it is returned unchanged. It is undefined
289*c8dee2aaSAndroid Build Coastguard Worker * if value is <= 0.
290*c8dee2aaSAndroid Build Coastguard Worker */
SkPrevPow2(int value)291*c8dee2aaSAndroid Build Coastguard Worker static inline int SkPrevPow2(int value) {
292*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(value > 0);
293*c8dee2aaSAndroid Build Coastguard Worker return 1 << SkPrevLog2(static_cast<uint32_t>(value));
294*c8dee2aaSAndroid Build Coastguard Worker }
295*c8dee2aaSAndroid Build Coastguard Worker
SkPrevPow2_portable(int value)296*c8dee2aaSAndroid Build Coastguard Worker constexpr int SkPrevPow2_portable(int value) {
297*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(value > 0);
298*c8dee2aaSAndroid Build Coastguard Worker return 1 << SkPrevLog2_portable(static_cast<uint32_t>(value));
299*c8dee2aaSAndroid Build Coastguard Worker }
300*c8dee2aaSAndroid Build Coastguard Worker
301*c8dee2aaSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
302*c8dee2aaSAndroid Build Coastguard Worker
303*c8dee2aaSAndroid Build Coastguard Worker /**
304*c8dee2aaSAndroid Build Coastguard Worker * Returns the next power of 2 >= n or n if the next power of 2 can't be represented by size_t.
305*c8dee2aaSAndroid Build Coastguard Worker */
SkNextSizePow2(size_t n)306*c8dee2aaSAndroid Build Coastguard Worker constexpr size_t SkNextSizePow2(size_t n) {
307*c8dee2aaSAndroid Build Coastguard Worker constexpr int kNumSizeTBits = 8 * sizeof(size_t);
308*c8dee2aaSAndroid Build Coastguard Worker constexpr size_t kHighBitSet = size_t(1) << (kNumSizeTBits - 1);
309*c8dee2aaSAndroid Build Coastguard Worker
310*c8dee2aaSAndroid Build Coastguard Worker if (!n) {
311*c8dee2aaSAndroid Build Coastguard Worker return 1;
312*c8dee2aaSAndroid Build Coastguard Worker } else if (n >= kHighBitSet) {
313*c8dee2aaSAndroid Build Coastguard Worker return n;
314*c8dee2aaSAndroid Build Coastguard Worker }
315*c8dee2aaSAndroid Build Coastguard Worker
316*c8dee2aaSAndroid Build Coastguard Worker n--;
317*c8dee2aaSAndroid Build Coastguard Worker uint32_t shift = 1;
318*c8dee2aaSAndroid Build Coastguard Worker while (shift < kNumSizeTBits) {
319*c8dee2aaSAndroid Build Coastguard Worker n |= n >> shift;
320*c8dee2aaSAndroid Build Coastguard Worker shift <<= 1;
321*c8dee2aaSAndroid Build Coastguard Worker }
322*c8dee2aaSAndroid Build Coastguard Worker return n + 1;
323*c8dee2aaSAndroid Build Coastguard Worker }
324*c8dee2aaSAndroid Build Coastguard Worker
325*c8dee2aaSAndroid Build Coastguard Worker // conservative check. will return false for very large values that "could" fit
SkFitsInFixed(T x)326*c8dee2aaSAndroid Build Coastguard Worker template <typename T> static inline bool SkFitsInFixed(T x) {
327*c8dee2aaSAndroid Build Coastguard Worker return SkTAbs(x) <= 32767.0f;
328*c8dee2aaSAndroid Build Coastguard Worker }
329*c8dee2aaSAndroid Build Coastguard Worker
330*c8dee2aaSAndroid Build Coastguard Worker #endif
331