00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef SkMath_DEFINED
00018 #define SkMath_DEFINED
00019
00020 #include "SkTypes.h"
00021
00023 int SkCLZ_portable(uint32_t);
00024
00029 int32_t SkMulShift(int32_t a, int32_t b, unsigned shift);
00030
00035 int32_t SkMulDiv(int32_t numer1, int32_t numer2, int32_t denom);
00036
00041 int32_t SkDivBits(int32_t numer, int32_t denom, int shift);
00042
00045 int32_t SkSqrtBits(int32_t value, int bitBias);
00046
00049 #define SkSqrt32(n) SkSqrtBits(n, 15)
00050
00053 int32_t SkCubeRootBits(int32_t value, int bitBias);
00054
00057 #define SkExtractSign(n) ((int32_t)(n) >> 31)
00058
00062 static inline int32_t SkApplySign(int32_t n, int32_t sign) {
00063 SkASSERT(sign == 0 || sign == -1);
00064 return (n ^ sign) - sign;
00065 }
00066
00069 static inline int SkClampPos(int value) {
00070 return value & ~(value >> 31);
00071 }
00072
00080 static inline int SkClampMax(int value, int max) {
00081
00082 SkASSERT(max >= 0);
00083
00084 SkASSERT(value >= 0 || max - value > 0);
00085
00086 #ifdef SK_CPU_HAS_CONDITIONAL_INSTR
00087 if (value < 0) {
00088 value = 0;
00089 }
00090 if (value > max) {
00091 value = max;
00092 }
00093 return value;
00094 #else
00095
00096 int diff = max - value;
00097
00098 diff &= diff >> 31;
00099
00100
00101 return (value + diff) & ~(value >> 31);
00102 #endif
00103 }
00104
00110 static inline unsigned SkClampUMax(unsigned value, unsigned max) {
00111 #ifdef SK_CPU_HAS_CONDITIONAL_INSTR
00112 if (value > max) {
00113 value = max;
00114 }
00115 return value;
00116 #else
00117 int diff = max - value;
00118
00119 diff &= diff >> 31;
00120
00121 return value + diff;
00122 #endif
00123 }
00124
00126
00127 #if defined(__arm__) && !defined(__thumb__)
00128 #define SkCLZ(x) __builtin_clz(x)
00129 #endif
00130
00131 #ifndef SkCLZ
00132 #define SkCLZ(x) SkCLZ_portable(x)
00133 #endif
00134
00136
00141 static inline int SkNextPow2(int value) {
00142 SkASSERT(value > 0);
00143 return 1 << (32 - SkCLZ(value - 1));
00144 }
00145
00154 static inline int SkNextLog2(uint32_t value) {
00155 SkASSERT(value != 0);
00156 return 32 - SkCLZ(value - 1);
00157 }
00158
00160
00165 #if defined(__arm__) \
00166 && !defined(__thumb__) \
00167 && !defined(__ARM_ARCH_4__) \
00168 && !defined(__ARM_ARCH_5T__)
00169 static inline int32_t SkMulS16(S16CPU x, S16CPU y) {
00170 SkASSERT((int16_t)x == x);
00171 SkASSERT((int16_t)y == y);
00172 int32_t product;
00173 asm("smulbb %0, %1, %2 \n"
00174 : "=r"(product)
00175 : "r"(x), "r"(y)
00176 );
00177 return product;
00178 }
00179 #else
00180 #ifdef SK_DEBUG
00181 static inline int32_t SkMulS16(S16CPU x, S16CPU y) {
00182 SkASSERT((int16_t)x == x);
00183 SkASSERT((int16_t)y == y);
00184 return x * y;
00185 }
00186 #else
00187 #define SkMulS16(x, y) ((x) * (y))
00188 #endif
00189 #endif
00190
00194 static inline U8CPU SkMulDiv255Trunc(U8CPU a, U8CPU b) {
00195 SkASSERT((uint8_t)a == a);
00196 SkASSERT((uint8_t)b == b);
00197 unsigned prod = SkMulS16(a, b) + 1;
00198 return (prod + (prod >> 8)) >> 8;
00199 }
00200
00204 static inline U8CPU SkMulDiv255Round(U8CPU a, U8CPU b) {
00205 SkASSERT((uint8_t)a == a);
00206 SkASSERT((uint8_t)b == b);
00207 unsigned prod = SkMulS16(a, b) + 128;
00208 return (prod + (prod >> 8)) >> 8;
00209 }
00210
00214 static inline unsigned SkMul16ShiftRound(unsigned a, unsigned b, int shift) {
00215 SkASSERT(a <= 32767);
00216 SkASSERT(b <= 32767);
00217 SkASSERT(shift > 0 && shift <= 8);
00218 unsigned prod = SkMulS16(a, b) + (1 << (shift - 1));
00219 return (prod + (prod >> shift)) >> shift;
00220 }
00221
00224 static inline unsigned SkDiv255Round(unsigned prod) {
00225 prod += 128;
00226 return (prod + (prod >> 8)) >> 8;
00227 }
00228
00229 #endif
00230