LCOV - code coverage report
Current view: top level - gfx/skia/skia/include/core - SkMath.h (source / functions) Hit Total Coverage
Test: output.info Lines: 17 33 51.5 %
Date: 2017-07-14 16:53:18 Functions: 5 11 45.5 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : // 64bit -> 32bit utilities
      16             : 
      17             : /**
      18             :  *  Return true iff the 64bit value can exactly be represented in signed 32bits
      19             :  */
      20        5157 : static inline bool sk_64_isS32(int64_t value) {
      21        5157 :     return (int32_t)value == value;
      22             : }
      23             : 
      24             : /**
      25             :  *  Return the 64bit argument as signed 32bits, asserting in debug that the arg
      26             :  *  exactly fits in signed 32bits. In the release build, no checks are preformed
      27             :  *  and the return value if the arg does not fit is undefined.
      28             :  */
      29        2509 : static inline int32_t sk_64_asS32(int64_t value) {
      30        2509 :     SkASSERT(sk_64_isS32(value));
      31        2509 :     return (int32_t)value;
      32             : }
      33             : 
      34             : // Handy util that can be passed two ints, and will automatically promote to
      35             : // 64bits before the multiply, so the caller doesn't have to remember to cast
      36             : // e.g. (int64_t)a * b;
      37        7837 : static inline int64_t sk_64_mul(int64_t a, int64_t b) {
      38        7837 :     return a * b;
      39             : }
      40             : 
      41             : ///////////////////////////////////////////////////////////////////////////////
      42             : 
      43             : /**
      44             :  *  Computes numer1 * numer2 / denom in full 64 intermediate precision.
      45             :  *  It is an error for denom to be 0. There is no special handling if
      46             :  *  the result overflows 32bits.
      47             :  */
      48           0 : static inline int32_t SkMulDiv(int32_t numer1, int32_t numer2, int32_t denom) {
      49           0 :     SkASSERT(denom);
      50             : 
      51           0 :     int64_t tmp = sk_64_mul(numer1, numer2) / denom;
      52           0 :     return sk_64_asS32(tmp);
      53             : }
      54             : 
      55             : /**
      56             :  *  Return the integer square root of value, with a bias of bitBias
      57             :  */
      58             : int32_t SkSqrtBits(int32_t value, int bitBias);
      59             : 
      60             : /** Return the integer square root of n, treated as a SkFixed (16.16)
      61             :  */
      62             : #define SkSqrt32(n)         SkSqrtBits(n, 15)
      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       17919 : static inline int SkClampMax(int value, int max) {
      78             :     // ensure that max is positive
      79       17919 :     SkASSERT(max >= 0);
      80       17919 :     if (value < 0) {
      81           0 :         value = 0;
      82             :     }
      83       17919 :     if (value > max) {
      84           0 :         value = max;
      85             :     }
      86       17919 :     return value;
      87             : }
      88             : 
      89             : /**
      90             :  *  Returns true if value is a power of 2. Does not explicitly check for
      91             :  *  value <= 0.
      92             :  */
      93           0 : template <typename T> constexpr inline bool SkIsPow2(T value) {
      94           0 :     return (value & (value - 1)) == 0;
      95             : }
      96             : 
      97             : ///////////////////////////////////////////////////////////////////////////////
      98             : 
      99             : /**
     100             :  *  Return a*b/((1 << shift) - 1), rounding any fractional bits.
     101             :  *  Only valid if a and b are unsigned and <= 32767 and shift is > 0 and <= 8
     102             :  */
     103           0 : static inline unsigned SkMul16ShiftRound(U16CPU a, U16CPU b, int shift) {
     104           0 :     SkASSERT(a <= 32767);
     105           0 :     SkASSERT(b <= 32767);
     106           0 :     SkASSERT(shift > 0 && shift <= 8);
     107           0 :     unsigned prod = a*b + (1 << (shift - 1));
     108           0 :     return (prod + (prod >> shift)) >> shift;
     109             : }
     110             : 
     111             : /**
     112             :  *  Return a*b/255, rounding any fractional bits.
     113             :  *  Only valid if a and b are unsigned and <= 32767.
     114             :  */
     115       65065 : static inline U8CPU SkMulDiv255Round(U16CPU a, U16CPU b) {
     116       65065 :     SkASSERT(a <= 32767);
     117       65065 :     SkASSERT(b <= 32767);
     118       65065 :     unsigned prod = a*b + 128;
     119       65065 :     return (prod + (prod >> 8)) >> 8;
     120             : }
     121             : 
     122             : /**
     123             :  * Stores numer/denom and numer%denom into div and mod respectively.
     124             :  */
     125             : template <typename In, typename Out>
     126             : inline void SkTDivMod(In numer, In denom, Out* div, Out* mod) {
     127             : #ifdef SK_CPU_ARM32
     128             :     // If we wrote this as in the else branch, GCC won't fuse the two into one
     129             :     // divmod call, but rather a div call followed by a divmod.  Silly!  This
     130             :     // version is just as fast as calling __aeabi_[u]idivmod manually, but with
     131             :     // prettier code.
     132             :     //
     133             :     // This benches as around 2x faster than the code in the else branch.
     134             :     const In d = numer/denom;
     135             :     *div = static_cast<Out>(d);
     136             :     *mod = static_cast<Out>(numer-d*denom);
     137             : #else
     138             :     // On x86 this will just be a single idiv.
     139             :     *div = static_cast<Out>(numer/denom);
     140             :     *mod = static_cast<Out>(numer%denom);
     141             : #endif
     142             : }
     143             : 
     144             : #endif

Generated by: LCOV version 1.13