LCOV - code coverage report
Current view: directory - gfx/skia/include/core - SkMath.h (source / functions) Found Hit Coverage
Test: app.info Lines: 35 0 0.0 %
Date: 2012-06-02 Functions: 8 0 0.0 %

       1                 : 
       2                 : /*
       3                 :  * Copyright 2006 The Android Open Source Project
       4                 :  *
       5                 :  * Use of this source code is governed by a BSD-style license that can be
       6                 :  * found in the LICENSE file.
       7                 :  */
       8                 : 
       9                 : 
      10                 : #ifndef SkMath_DEFINED
      11                 : #define SkMath_DEFINED
      12                 : 
      13                 : #include "SkTypes.h"
      14                 : 
      15                 : //! Returns the number of leading zero bits (0...32)
      16                 : int SkCLZ_portable(uint32_t);
      17                 : 
      18                 : /** Computes the 64bit product of a * b, and then shifts the answer down by
      19                 :     shift bits, returning the low 32bits. shift must be [0..63]
      20                 :     e.g. to perform a fixedmul, call SkMulShift(a, b, 16)
      21                 : */
      22                 : int32_t SkMulShift(int32_t a, int32_t b, unsigned shift);
      23                 : 
      24                 : /** Computes numer1 * numer2 / denom in full 64 intermediate precision.
      25                 :     It is an error for denom to be 0. There is no special handling if
      26                 :     the result overflows 32bits.
      27                 : */
      28                 : int32_t SkMulDiv(int32_t numer1, int32_t numer2, int32_t denom);
      29                 : 
      30                 : /** Computes (numer1 << shift) / denom in full 64 intermediate precision.
      31                 :     It is an error for denom to be 0. There is no special handling if
      32                 :     the result overflows 32bits.
      33                 : */
      34                 : int32_t SkDivBits(int32_t numer, int32_t denom, int shift);
      35                 : 
      36                 : /** Return the integer square root of value, with a bias of bitBias
      37                 : */
      38                 : int32_t SkSqrtBits(int32_t value, int bitBias);
      39                 : 
      40                 : /** Return the integer square root of n, treated as a SkFixed (16.16)
      41                 : */
      42                 : #define SkSqrt32(n)         SkSqrtBits(n, 15)
      43                 : 
      44                 : /** Return the integer cube root of value, with a bias of bitBias
      45                 :  */
      46                 : int32_t SkCubeRootBits(int32_t value, int bitBias);
      47                 : 
      48                 : /** Returns -1 if n < 0, else returns 0
      49                 : */
      50                 : #define SkExtractSign(n)    ((int32_t)(n) >> 31)
      51                 : 
      52                 : /** If sign == -1, returns -n, else sign must be 0, and returns n.
      53                 :     Typically used in conjunction with SkExtractSign().
      54                 : */
      55               0 : static inline int32_t SkApplySign(int32_t n, int32_t sign) {
      56               0 :     SkASSERT(sign == 0 || sign == -1);
      57               0 :     return (n ^ sign) - sign;
      58                 : }
      59                 : 
      60                 : /** Return x with the sign of y */
      61                 : static inline int32_t SkCopySign32(int32_t x, int32_t y) {
      62                 :     return SkApplySign(x, SkExtractSign(x ^ y));
      63                 : }
      64                 : 
      65                 : /** Returns (value < 0 ? 0 : value) efficiently (i.e. no compares or branches)
      66                 : */
      67               0 : static inline int SkClampPos(int value) {
      68               0 :     return value & ~(value >> 31);
      69                 : }
      70                 : 
      71                 : /** Given an integer and a positive (max) integer, return the value
      72                 :     pinned against 0 and max, inclusive.
      73                 :     @param value    The value we want returned pinned between [0...max]
      74                 :     @param max      The positive max value
      75                 :     @return 0 if value < 0, max if value > max, else value
      76                 : */
      77               0 : static inline int SkClampMax(int value, int max) {
      78                 :     // ensure that max is positive
      79               0 :     SkASSERT(max >= 0);
      80               0 :     if (value < 0) {
      81               0 :         value = 0;
      82                 :     }
      83               0 :     if (value > max) {
      84               0 :         value = max;
      85                 :     }
      86               0 :     return value;
      87                 : }
      88                 : 
      89                 : /** Given a positive value and a positive max, return the value
      90                 :     pinned against max.
      91                 :     Note: only works as long as max - value doesn't wrap around
      92                 :     @return max if value >= max, else value
      93                 : */
      94                 : static inline unsigned SkClampUMax(unsigned value, unsigned max) {
      95                 : #ifdef SK_CPU_HAS_CONDITIONAL_INSTR
      96                 :     if (value > max) {
      97                 :         value = max;
      98                 :     }
      99                 :     return value;
     100                 : #else
     101                 :     int diff = max - value;
     102                 :     // clear diff if diff is positive
     103                 :     diff &= diff >> 31;
     104                 : 
     105                 :     return value + diff;
     106                 : #endif
     107                 : }
     108                 : 
     109                 : ///////////////////////////////////////////////////////////////////////////////
     110                 : 
     111                 : #if defined(__arm__)
     112                 :     #define SkCLZ(x)    __builtin_clz(x)
     113                 : #endif
     114                 : 
     115                 : #ifndef SkCLZ
     116                 :     #define SkCLZ(x)    SkCLZ_portable(x)
     117                 : #endif
     118                 : 
     119                 : ///////////////////////////////////////////////////////////////////////////////
     120                 : 
     121                 : /** Returns the smallest power-of-2 that is >= the specified value. If value
     122                 :     is already a power of 2, then it is returned unchanged. It is undefined
     123                 :     if value is <= 0.
     124                 : */
     125                 : static inline int SkNextPow2(int value) {
     126                 :     SkASSERT(value > 0);
     127                 :     return 1 << (32 - SkCLZ(value - 1));
     128                 : }
     129                 : 
     130                 : /** Returns the log2 of the specified value, were that value to be rounded up
     131                 :     to the next power of 2. It is undefined to pass 0. Examples:
     132                 :          SkNextLog2(1) -> 0
     133                 :          SkNextLog2(2) -> 1
     134                 :          SkNextLog2(3) -> 2
     135                 :          SkNextLog2(4) -> 2
     136                 :          SkNextLog2(5) -> 3
     137                 : */
     138                 : static inline int SkNextLog2(uint32_t value) {
     139                 :     SkASSERT(value != 0);
     140                 :     return 32 - SkCLZ(value - 1);
     141                 : }
     142                 : 
     143                 : /** Returns true if value is a power of 2. Does not explicitly check for
     144                 :     value <= 0.
     145                 :  */
     146                 : static inline bool SkIsPow2(int value) {
     147                 :     return (value & (value - 1)) == 0;
     148                 : }
     149                 : 
     150                 : ///////////////////////////////////////////////////////////////////////////////
     151                 : 
     152                 : /** SkMulS16(a, b) multiplies a * b, but requires that a and b are both int16_t.
     153                 :     With this requirement, we can generate faster instructions on some
     154                 :     architectures.
     155                 : */
     156                 : #if defined(__arm__) \
     157                 :   && !defined(__thumb__) \
     158                 :   && !defined(__ARM_ARCH_4T__) \
     159                 :   && !defined(__ARM_ARCH_5T__)
     160                 :     static inline int32_t SkMulS16(S16CPU x, S16CPU y) {
     161                 :         SkASSERT((int16_t)x == x);
     162                 :         SkASSERT((int16_t)y == y);
     163                 :         int32_t product;
     164                 :         asm("smulbb %0, %1, %2 \n"
     165                 :             : "=r"(product)
     166                 :             : "r"(x), "r"(y)
     167                 :             );
     168                 :         return product;
     169                 :     }
     170                 : #else
     171                 :     #ifdef SK_DEBUG
     172               0 :         static inline int32_t SkMulS16(S16CPU x, S16CPU y) {
     173               0 :             SkASSERT((int16_t)x == x);
     174               0 :             SkASSERT((int16_t)y == y);
     175               0 :             return x * y;
     176                 :         }
     177                 :     #else
     178                 :         #define SkMulS16(x, y)  ((x) * (y))
     179                 :     #endif
     180                 : #endif
     181                 : 
     182                 : /** Return a*b/255, truncating away any fractional bits. Only valid if both
     183                 :     a and b are 0..255
     184                 : */
     185                 : static inline U8CPU SkMulDiv255Trunc(U8CPU a, U8CPU b) {
     186                 :     SkASSERT((uint8_t)a == a);
     187                 :     SkASSERT((uint8_t)b == b);
     188                 :     unsigned prod = SkMulS16(a, b) + 1;
     189                 :     return (prod + (prod >> 8)) >> 8;
     190                 : }
     191                 : 
     192                 : /** Return a*b/255, rounding any fractional bits. Only valid if both
     193                 :     a and b are 0..255
     194                 :  */
     195               0 : static inline U8CPU SkMulDiv255Round(U8CPU a, U8CPU b) {
     196               0 :     SkASSERT((uint8_t)a == a);
     197               0 :     SkASSERT((uint8_t)b == b);
     198               0 :     unsigned prod = SkMulS16(a, b) + 128;
     199               0 :     return (prod + (prod >> 8)) >> 8;
     200                 : }
     201                 : 
     202                 : /** Return (a*b)/255, taking the ceiling of any fractional bits. Only valid if
     203                 :     both a and b are 0..255. The expected result equals (a * b + 254) / 255.
     204                 :  */
     205               0 : static inline U8CPU SkMulDiv255Ceiling(U8CPU a, U8CPU b) {
     206               0 :     SkASSERT((uint8_t)a == a);
     207               0 :     SkASSERT((uint8_t)b == b);
     208               0 :     unsigned prod = SkMulS16(a, b) + 255;
     209               0 :     return (prod + (prod >> 8)) >> 8;
     210                 : }
     211                 : 
     212                 : /** Return a*b/((1 << shift) - 1), rounding any fractional bits.
     213                 :     Only valid if a and b are unsigned and <= 32767 and shift is > 0 and <= 8
     214                 : */
     215               0 : static inline unsigned SkMul16ShiftRound(unsigned a, unsigned b, int shift) {
     216               0 :     SkASSERT(a <= 32767);
     217               0 :     SkASSERT(b <= 32767);
     218               0 :     SkASSERT(shift > 0 && shift <= 8);
     219               0 :     unsigned prod = SkMulS16(a, b) + (1 << (shift - 1));
     220               0 :     return (prod + (prod >> shift)) >> shift;
     221                 : }
     222                 : 
     223                 : /** Just the rounding step in SkDiv255Round: round(value / 255)
     224                 :  */
     225               0 : static inline unsigned SkDiv255Round(unsigned prod) {
     226               0 :     prod += 128;
     227               0 :     return (prod + (prod >> 8)) >> 8;
     228                 : }
     229                 : 
     230                 : #endif
     231                 : 

Generated by: LCOV version 1.7