gfx/skia/trunk/include/core/SkMath.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/skia/trunk/include/core/SkMath.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,224 @@
     1.4 +
     1.5 +/*
     1.6 + * Copyright 2006 The Android Open Source Project
     1.7 + *
     1.8 + * Use of this source code is governed by a BSD-style license that can be
     1.9 + * found in the LICENSE file.
    1.10 + */
    1.11 +
    1.12 +
    1.13 +#ifndef SkMath_DEFINED
    1.14 +#define SkMath_DEFINED
    1.15 +
    1.16 +#include "SkTypes.h"
    1.17 +
    1.18 +/**
    1.19 + *  Computes numer1 * numer2 / denom in full 64 intermediate precision.
    1.20 + *  It is an error for denom to be 0. There is no special handling if
    1.21 + *  the result overflows 32bits.
    1.22 + */
    1.23 +int32_t SkMulDiv(int32_t numer1, int32_t numer2, int32_t denom);
    1.24 +
    1.25 +/**
    1.26 + *  Computes (numer1 << shift) / denom in full 64 intermediate precision.
    1.27 + *  It is an error for denom to be 0. There is no special handling if
    1.28 + *  the result overflows 32bits.
    1.29 + */
    1.30 +int32_t SkDivBits(int32_t numer, int32_t denom, int shift);
    1.31 +
    1.32 +/**
    1.33 + *  Return the integer square root of value, with a bias of bitBias
    1.34 + */
    1.35 +int32_t SkSqrtBits(int32_t value, int bitBias);
    1.36 +
    1.37 +/** Return the integer square root of n, treated as a SkFixed (16.16)
    1.38 + */
    1.39 +#define SkSqrt32(n)         SkSqrtBits(n, 15)
    1.40 +
    1.41 +// 64bit -> 32bit utilities
    1.42 +
    1.43 +/**
    1.44 + *  Return true iff the 64bit value can exactly be represented in signed 32bits
    1.45 + */
    1.46 +static inline bool sk_64_isS32(int64_t value) {
    1.47 +    return (int32_t)value == value;
    1.48 +}
    1.49 +
    1.50 +/**
    1.51 + *  Return the 64bit argument as signed 32bits, asserting in debug that the arg
    1.52 + *  exactly fits in signed 32bits. In the release build, no checks are preformed
    1.53 + *  and the return value if the arg does not fit is undefined.
    1.54 + */
    1.55 +static inline int32_t sk_64_asS32(int64_t value) {
    1.56 +    SkASSERT(sk_64_isS32(value));
    1.57 +    return (int32_t)value;
    1.58 +}
    1.59 +
    1.60 +// Handy util that can be passed two ints, and will automatically promote to
    1.61 +// 64bits before the multiply, so the caller doesn't have to remember to cast
    1.62 +// e.g. (int64_t)a * b;
    1.63 +static inline int64_t sk_64_mul(int64_t a, int64_t b) {
    1.64 +    return a * b;
    1.65 +}
    1.66 +
    1.67 +///////////////////////////////////////////////////////////////////////////////
    1.68 +
    1.69 +//! Returns the number of leading zero bits (0...32)
    1.70 +int SkCLZ_portable(uint32_t);
    1.71 +
    1.72 +#ifndef SkCLZ
    1.73 +    #if defined(_MSC_VER) && _MSC_VER >= 1400
    1.74 +        #include <intrin.h>
    1.75 +
    1.76 +        static inline int SkCLZ(uint32_t mask) {
    1.77 +            if (mask) {
    1.78 +                DWORD index;
    1.79 +                _BitScanReverse(&index, mask);
    1.80 +                return index ^ 0x1F;
    1.81 +            } else {
    1.82 +                return 32;
    1.83 +            }
    1.84 +        }
    1.85 +    #elif defined(SK_CPU_ARM) || defined(__GNUC__) || defined(__clang__)
    1.86 +        static inline int SkCLZ(uint32_t mask) {
    1.87 +            // __builtin_clz(0) is undefined, so we have to detect that case.
    1.88 +            return mask ? __builtin_clz(mask) : 32;
    1.89 +        }
    1.90 +    #else
    1.91 +        #define SkCLZ(x)    SkCLZ_portable(x)
    1.92 +    #endif
    1.93 +#endif
    1.94 +
    1.95 +/**
    1.96 + *  Returns (value < 0 ? 0 : value) efficiently (i.e. no compares or branches)
    1.97 + */
    1.98 +static inline int SkClampPos(int value) {
    1.99 +    return value & ~(value >> 31);
   1.100 +}
   1.101 +
   1.102 +/** Given an integer and a positive (max) integer, return the value
   1.103 + *  pinned against 0 and max, inclusive.
   1.104 + *  @param value    The value we want returned pinned between [0...max]
   1.105 + *  @param max      The positive max value
   1.106 + *  @return 0 if value < 0, max if value > max, else value
   1.107 + */
   1.108 +static inline int SkClampMax(int value, int max) {
   1.109 +    // ensure that max is positive
   1.110 +    SkASSERT(max >= 0);
   1.111 +    if (value < 0) {
   1.112 +        value = 0;
   1.113 +    }
   1.114 +    if (value > max) {
   1.115 +        value = max;
   1.116 +    }
   1.117 +    return value;
   1.118 +}
   1.119 +
   1.120 +/**
   1.121 + *  Returns the smallest power-of-2 that is >= the specified value. If value
   1.122 + *  is already a power of 2, then it is returned unchanged. It is undefined
   1.123 + *  if value is <= 0.
   1.124 + */
   1.125 +static inline int SkNextPow2(int value) {
   1.126 +    SkASSERT(value > 0);
   1.127 +    return 1 << (32 - SkCLZ(value - 1));
   1.128 +}
   1.129 +
   1.130 +/**
   1.131 + *  Returns the log2 of the specified value, were that value to be rounded up
   1.132 + *  to the next power of 2. It is undefined to pass 0. Examples:
   1.133 + *  SkNextLog2(1) -> 0
   1.134 + *  SkNextLog2(2) -> 1
   1.135 + *  SkNextLog2(3) -> 2
   1.136 + *  SkNextLog2(4) -> 2
   1.137 + *  SkNextLog2(5) -> 3
   1.138 + */
   1.139 +static inline int SkNextLog2(uint32_t value) {
   1.140 +    SkASSERT(value != 0);
   1.141 +    return 32 - SkCLZ(value - 1);
   1.142 +}
   1.143 +
   1.144 +/**
   1.145 + *  Returns true if value is a power of 2. Does not explicitly check for
   1.146 + *  value <= 0.
   1.147 + */
   1.148 +static inline bool SkIsPow2(int value) {
   1.149 +    return (value & (value - 1)) == 0;
   1.150 +}
   1.151 +
   1.152 +///////////////////////////////////////////////////////////////////////////////
   1.153 +
   1.154 +/**
   1.155 + *  SkMulS16(a, b) multiplies a * b, but requires that a and b are both int16_t.
   1.156 + *  With this requirement, we can generate faster instructions on some
   1.157 + *  architectures.
   1.158 + */
   1.159 +#ifdef SK_ARM_HAS_EDSP
   1.160 +    static inline int32_t SkMulS16(S16CPU x, S16CPU y) {
   1.161 +        SkASSERT((int16_t)x == x);
   1.162 +        SkASSERT((int16_t)y == y);
   1.163 +        int32_t product;
   1.164 +        asm("smulbb %0, %1, %2 \n"
   1.165 +            : "=r"(product)
   1.166 +            : "r"(x), "r"(y)
   1.167 +            );
   1.168 +        return product;
   1.169 +    }
   1.170 +#else
   1.171 +    #ifdef SK_DEBUG
   1.172 +        static inline int32_t SkMulS16(S16CPU x, S16CPU y) {
   1.173 +            SkASSERT((int16_t)x == x);
   1.174 +            SkASSERT((int16_t)y == y);
   1.175 +            return x * y;
   1.176 +        }
   1.177 +    #else
   1.178 +        #define SkMulS16(x, y)  ((x) * (y))
   1.179 +    #endif
   1.180 +#endif
   1.181 +
   1.182 +/**
   1.183 + *  Return a*b/((1 << shift) - 1), rounding any fractional bits.
   1.184 + *  Only valid if a and b are unsigned and <= 32767 and shift is > 0 and <= 8
   1.185 + */
   1.186 +static inline unsigned SkMul16ShiftRound(U16CPU a, U16CPU b, int shift) {
   1.187 +    SkASSERT(a <= 32767);
   1.188 +    SkASSERT(b <= 32767);
   1.189 +    SkASSERT(shift > 0 && shift <= 8);
   1.190 +    unsigned prod = SkMulS16(a, b) + (1 << (shift - 1));
   1.191 +    return (prod + (prod >> shift)) >> shift;
   1.192 +}
   1.193 +
   1.194 +/**
   1.195 + *  Return a*b/255, rounding any fractional bits.
   1.196 + *  Only valid if a and b are unsigned and <= 32767.
   1.197 + */
   1.198 +static inline U8CPU SkMulDiv255Round(U16CPU a, U16CPU b) {
   1.199 +    SkASSERT(a <= 32767);
   1.200 +    SkASSERT(b <= 32767);
   1.201 +    unsigned prod = SkMulS16(a, b) + 128;
   1.202 +    return (prod + (prod >> 8)) >> 8;
   1.203 +}
   1.204 +
   1.205 +/**
   1.206 + * Stores numer/denom and numer%denom into div and mod respectively.
   1.207 + */
   1.208 +template <typename In, typename Out>
   1.209 +inline void SkTDivMod(In numer, In denom, Out* div, Out* mod) {
   1.210 +#ifdef SK_CPU_ARM
   1.211 +    // If we wrote this as in the else branch, GCC won't fuse the two into one
   1.212 +    // divmod call, but rather a div call followed by a divmod.  Silly!  This
   1.213 +    // version is just as fast as calling __aeabi_[u]idivmod manually, but with
   1.214 +    // prettier code.
   1.215 +    //
   1.216 +    // This benches as around 2x faster than the code in the else branch.
   1.217 +    const In d = numer/denom;
   1.218 +    *div = static_cast<Out>(d);
   1.219 +    *mod = static_cast<Out>(numer-d*denom);
   1.220 +#else
   1.221 +    // On x86 this will just be a single idiv.
   1.222 +    *div = static_cast<Out>(numer/denom);
   1.223 +    *mod = static_cast<Out>(numer%denom);
   1.224 +#endif  // SK_CPU_ARM
   1.225 +}
   1.226 +
   1.227 +#endif

mercurial