LCOV - code coverage report
Current view: directory - gfx/skia/src/core - SkFloat.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 127 0 0.0 %
Date: 2012-06-02 Functions: 19 0 0.0 %

       1                 : 
       2                 : /*
       3                 :  * Copyright 2008 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                 : #include "SkFloat.h"
      11                 : #include "SkMath.h"
      12                 : 
      13                 : #define EXP_BIAS    (127+23)
      14                 : 
      15               0 : static int get_unsigned_exp(uint32_t packed)
      16                 : {
      17               0 :     return (packed << 1 >> 24);
      18                 : }
      19                 : 
      20               0 : static unsigned get_unsigned_value(uint32_t packed)
      21                 : {
      22               0 :     return (packed << 9 >> 9) | (1 << 23);
      23                 : }
      24                 : 
      25               0 : static int get_signed_value(int32_t packed)
      26                 : {
      27               0 :     return SkApplySign(get_unsigned_value(packed), SkExtractSign(packed));
      28                 : }
      29                 : 
      30                 : /////////////////////////////////////////////////////////////////////////
      31                 : 
      32               0 : int SkFloat::GetShift(int32_t packed, int shift)
      33                 : {
      34               0 :     if (packed == 0)
      35               0 :         return 0;
      36                 : 
      37               0 :     int exp = get_unsigned_exp(packed) - EXP_BIAS - shift;
      38               0 :     int value = get_unsigned_value(packed);
      39                 : 
      40               0 :     if (exp >= 0)
      41                 :     {
      42               0 :         if (exp > 8)    // overflow
      43               0 :             value = SK_MaxS32;
      44                 :         else
      45               0 :             value <<= exp;
      46                 :     }
      47                 :     else
      48                 :     {
      49               0 :         exp = -exp;
      50               0 :         if (exp > 23)   // underflow
      51               0 :             value = 0;
      52                 :         else
      53               0 :             value >>= exp;
      54                 :     }
      55               0 :     return SkApplySign(value, SkExtractSign(packed));
      56                 : }
      57                 : 
      58                 : /////////////////////////////////////////////////////////////////////////////////////
      59                 : 
      60               0 : int32_t SkFloat::SetShift(int value, int shift)
      61                 : {
      62               0 :     if (value == 0)
      63               0 :         return 0;
      64                 : 
      65                 :     // record the sign and make value positive
      66               0 :     int sign = SkExtractSign(value);
      67               0 :     value = SkApplySign(value, sign);
      68                 : 
      69               0 :     if (value >> 24)    // value is too big (has more than 24 bits set)
      70                 :     {
      71               0 :         int bias = 8 - SkCLZ(value);
      72               0 :         SkASSERT(bias > 0 && bias < 8);
      73               0 :         value >>= bias;
      74               0 :         shift += bias;
      75                 :     }
      76                 :     else
      77                 :     {
      78               0 :         int zeros = SkCLZ(value << 8);
      79               0 :         SkASSERT(zeros >= 0 && zeros <= 23);
      80               0 :         value <<= zeros;
      81               0 :         shift -= zeros;
      82                 :     }
      83                 :     // now value is left-aligned to 24 bits
      84               0 :     SkASSERT((value >> 23) == 1);
      85                 : 
      86               0 :     shift += EXP_BIAS;
      87               0 :     if (shift < 0)  // underflow
      88               0 :         return 0;
      89                 :     else
      90                 :     {
      91               0 :         if (shift > 255)    // overflow
      92                 :         {
      93               0 :             shift = 255;
      94               0 :             value = 0x00FFFFFF;
      95                 :         }
      96               0 :         int32_t packed = sign << 31;        // set the sign-bit
      97               0 :         packed |= shift << 23;          // store the packed exponent
      98               0 :         packed |= ((unsigned)(value << 9) >> 9);    // clear 24th bit of value (its implied)
      99                 : 
     100                 : #ifdef SK_DEBUG
     101                 :         {
     102                 :             int n;
     103                 : 
     104               0 :             n = SkExtractSign(packed);
     105               0 :             SkASSERT(n == sign);
     106               0 :             n = get_unsigned_exp(packed);
     107               0 :             SkASSERT(n == shift);
     108               0 :             n = get_unsigned_value(packed);
     109               0 :             SkASSERT(n == value);
     110                 :         }
     111                 : #endif
     112               0 :         return packed;
     113                 :     }
     114                 : }
     115                 : 
     116               0 : int32_t SkFloat::Neg(int32_t packed)
     117                 : {
     118               0 :     if (packed)
     119               0 :         packed = packed ^ (1 << 31);
     120               0 :     return packed;
     121                 : }
     122                 : 
     123               0 : int32_t SkFloat::Add(int32_t packed_a, int32_t packed_b)
     124                 : {
     125               0 :     if (packed_a == 0)
     126               0 :         return packed_b;
     127               0 :     if (packed_b == 0)
     128               0 :         return packed_a;
     129                 : 
     130               0 :     int exp_a = get_unsigned_exp(packed_a);
     131               0 :     int exp_b = get_unsigned_exp(packed_b);
     132               0 :     int exp_diff = exp_a - exp_b;
     133                 : 
     134               0 :     int shift_a = 0, shift_b = 0;
     135                 :     int exp;
     136                 : 
     137               0 :     if (exp_diff >= 0)
     138                 :     {
     139               0 :         if (exp_diff > 24)  // B is too small to contribute
     140               0 :             return packed_a;
     141               0 :         shift_b = exp_diff;
     142               0 :         exp = exp_a;
     143                 :     }
     144                 :     else
     145                 :     {
     146               0 :         exp_diff = -exp_diff;
     147               0 :         if (exp_diff > 24)  // A is too small to contribute
     148               0 :             return packed_b;
     149               0 :         shift_a = exp_diff;
     150               0 :         exp = exp_b;
     151                 :     }
     152                 : 
     153               0 :     int value_a = get_signed_value(packed_a) >> shift_a;
     154               0 :     int value_b = get_signed_value(packed_b) >> shift_b;
     155                 : 
     156               0 :     return SkFloat::SetShift(value_a + value_b, exp - EXP_BIAS);
     157                 : }
     158                 : 
     159                 : #include "Sk64.h"
     160                 : 
     161               0 : static inline int32_t mul24(int32_t a, int32_t b)
     162                 : {
     163                 :     Sk64 tmp;
     164                 : 
     165               0 :     tmp.setMul(a, b);
     166               0 :     tmp.roundRight(24);
     167               0 :     return tmp.get32();
     168                 : }
     169                 : 
     170               0 : int32_t SkFloat::Mul(int32_t packed_a, int32_t packed_b)
     171                 : {
     172               0 :     if (packed_a == 0 || packed_b == 0)
     173               0 :         return 0;
     174                 : 
     175               0 :     int exp_a = get_unsigned_exp(packed_a);
     176               0 :     int exp_b = get_unsigned_exp(packed_b);
     177                 : 
     178               0 :     int value_a = get_signed_value(packed_a);
     179               0 :     int value_b = get_signed_value(packed_b);
     180                 : 
     181               0 :     return SkFloat::SetShift(mul24(value_a, value_b), exp_a + exp_b - 2*EXP_BIAS + 24);
     182                 : }
     183                 : 
     184               0 : int32_t SkFloat::MulInt(int32_t packed, int n)
     185                 : {
     186               0 :     return Mul(packed, SetShift(n, 0));
     187                 : }
     188                 : 
     189               0 : int32_t SkFloat::Div(int32_t packed_n, int32_t packed_d)
     190                 : {
     191               0 :     SkASSERT(packed_d != 0);
     192                 : 
     193               0 :     if (packed_n == 0)
     194               0 :         return 0;
     195                 : 
     196               0 :     int exp_n = get_unsigned_exp(packed_n);
     197               0 :     int exp_d = get_unsigned_exp(packed_d);
     198                 : 
     199               0 :     int value_n = get_signed_value(packed_n);
     200               0 :     int value_d = get_signed_value(packed_d);
     201                 : 
     202               0 :     return SkFloat::SetShift(SkDivBits(value_n, value_d, 24), exp_n - exp_d - 24);
     203                 : }
     204                 : 
     205               0 : int32_t SkFloat::DivInt(int32_t packed, int n)
     206                 : {
     207               0 :     return Div(packed, SetShift(n, 0));
     208                 : }
     209                 : 
     210               0 : int32_t SkFloat::Invert(int32_t packed)
     211                 : {
     212               0 :     return Div(packed, SetShift(1, 0));
     213                 : }
     214                 : 
     215               0 : int32_t SkFloat::Sqrt(int32_t packed)
     216                 : {
     217               0 :     if (packed < 0)
     218                 :     {
     219               0 :         SkDEBUGFAIL("can't sqrt a negative number");
     220               0 :         return 0;
     221                 :     }
     222                 : 
     223               0 :     int exp = get_unsigned_exp(packed);
     224               0 :     int value = get_unsigned_value(packed);
     225                 : 
     226               0 :     int nexp = exp - EXP_BIAS;
     227               0 :     int root = SkSqrtBits(value << (nexp & 1), 26);
     228               0 :     nexp >>= 1;
     229               0 :     return SkFloat::SetShift(root, nexp - 11);
     230                 : }
     231                 : 
     232                 : #if defined _WIN32 && _MSC_VER >= 1300  // disable warning : unreachable code
     233                 : #pragma warning ( push )
     234                 : #pragma warning ( disable : 4702 )
     235                 : #endif
     236                 : 
     237               0 : int32_t SkFloat::CubeRoot(int32_t packed)
     238                 : {
     239               0 :     sk_throw();
     240               0 :     return 0;
     241                 : }
     242                 : 
     243                 : #if defined _WIN32 && _MSC_VER >= 1300
     244                 : #pragma warning ( pop )
     245                 : #endif
     246                 : 
     247               0 : static inline int32_t clear_high_bit(int32_t n)
     248                 : {
     249               0 :     return ((uint32_t)(n << 1)) >> 1;
     250                 : }
     251                 : 
     252               0 : static inline int int_sign(int32_t a, int32_t b)
     253                 : {
     254               0 :     return a > b ? 1 : (a < b ? -1 : 0);
     255                 : }
     256                 : 
     257               0 : int SkFloat::Cmp(int32_t packed_a, int32_t packed_b)
     258                 : {
     259               0 :     packed_a = SkApplySign(clear_high_bit(packed_a), SkExtractSign(packed_a));
     260               0 :     packed_b = SkApplySign(clear_high_bit(packed_b), SkExtractSign(packed_b));
     261                 : 
     262               0 :     return int_sign(packed_a, packed_b);
     263                 : }
     264                 : 
     265                 : /////////////////////////////////////////////////////////////////////////////////////
     266                 : /////////////////////////////////////////////////////////////////////////////////////
     267                 : 
     268                 : #ifdef SK_DEBUG
     269                 : 
     270                 : #include "SkRandom.h"
     271                 : #ifdef SK_CAN_USE_FLOAT
     272                 :     #include "SkFloatingPoint.h"
     273                 : #endif
     274                 : 
     275               0 : void SkFloat::UnitTest()
     276                 : {
     277                 : #ifdef SK_SUPPORT_UNITTEST
     278                 :     SkFloat a, b, c, d;
     279                 :     int     n;
     280                 : 
     281                 :     a.setZero();
     282                 :     n = a.getInt();
     283                 :     SkASSERT(n == 0);
     284                 : 
     285                 :     b.setInt(5);
     286                 :     n = b.getInt();
     287                 :     SkASSERT(n == 5);
     288                 : 
     289                 :     c.setInt(-3);
     290                 :     n = c.getInt();
     291                 :     SkASSERT(n == -3);
     292                 : 
     293                 :     d.setAdd(c, b);
     294                 :     SkDebugf("SkFloat: %d + %d = %d\n", c.getInt(), b.getInt(), d.getInt());    
     295                 : 
     296                 :     SkRandom    rand;
     297                 : 
     298                 : #ifdef SK_CAN_USE_FLOAT
     299                 :     int i;
     300                 :     for (i = 0; i < 1000; i++)
     301                 :     {
     302                 :         float fa, fb;
     303                 :         int aa = rand.nextS() >> 14;
     304                 :         int bb = rand.nextS() >> 14;
     305                 :         a.setInt(aa);
     306                 :         b.setInt(bb);
     307                 :         SkASSERT(a.getInt() == aa);
     308                 :         SkASSERT(b.getInt() == bb);
     309                 : 
     310                 :         c.setAdd(a, b);
     311                 :         int cc = c.getInt();
     312                 :         SkASSERT(cc == aa + bb);
     313                 : 
     314                 :         c.setSub(a, b);
     315                 :         cc = c.getInt();
     316                 :         SkASSERT(cc == aa - bb);
     317                 : 
     318                 :         aa >>= 5;
     319                 :         bb >>= 5;
     320                 :         a.setInt(aa);
     321                 :         b.setInt(bb);
     322                 :         c.setMul(a, b);
     323                 :         cc = c.getInt();
     324                 :         SkASSERT(cc == aa * bb);
     325                 :         /////////////////////////////////////
     326                 : 
     327                 :         aa = rand.nextS() >> 11;
     328                 :         a.setFixed(aa);
     329                 :         cc = a.getFixed();
     330                 :         SkASSERT(aa == cc);
     331                 : 
     332                 :         bb = rand.nextS() >> 11;
     333                 :         b.setFixed(bb);
     334                 :         cc = b.getFixed();
     335                 :         SkASSERT(bb == cc);
     336                 : 
     337                 :         cc = SkFixedMul(aa, bb);
     338                 :         c.setMul(a, b);
     339                 :         SkFixed dd = c.getFixed();
     340                 :         int diff = cc - dd;
     341                 :         SkASSERT(SkAbs32(diff) <= 1);
     342                 : 
     343                 :         fa = (float)aa / 65536.0f;
     344                 :         fb = (float)bb / 65536.0f;
     345                 :         a.assertEquals(fa);
     346                 :         b.assertEquals(fb);
     347                 :         fa = a.getFloat();
     348                 :         fb = b.getFloat();
     349                 : 
     350                 :         c.assertEquals(fa * fb, 1);
     351                 : 
     352                 :         c.setDiv(a, b);
     353                 :         cc = SkFixedDiv(aa, bb);
     354                 :         dd = c.getFixed();
     355                 :         diff = cc - dd;
     356                 :         SkASSERT(SkAbs32(diff) <= 3);
     357                 : 
     358                 :         c.assertEquals(fa / fb, 1);
     359                 : 
     360                 :         SkASSERT((aa == bb) == (a == b));
     361                 :         SkASSERT((aa != bb) == (a != b));
     362                 :         SkASSERT((aa < bb) == (a < b));
     363                 :         SkASSERT((aa <= bb) == (a <= b));
     364                 :         SkASSERT((aa > bb) == (a > b));
     365                 :         SkASSERT((aa >= bb) == (a >= b));
     366                 : 
     367                 :         if (aa < 0)
     368                 :         {
     369                 :             aa = -aa;
     370                 :             fa = -fa;
     371                 :         }
     372                 :         a.setFixed(aa);
     373                 :         c.setSqrt(a);
     374                 :         cc = SkFixedSqrt(aa);
     375                 :         dd = c.getFixed();
     376                 :         SkASSERT(dd == cc);
     377                 : 
     378                 :         c.assertEquals(sk_float_sqrt(fa), 2);
     379                 : 
     380                 :         // cuberoot
     381                 : #if 0
     382                 :         a.setInt(1);
     383                 :         a.cubeRoot();
     384                 :         a.assertEquals(1.0f, 0);
     385                 :         a.setInt(8);
     386                 :         a.cubeRoot();
     387                 :         a.assertEquals(2.0f, 0);
     388                 :         a.setInt(27);
     389                 :         a.cubeRoot();
     390                 :         a.assertEquals(3.0f, 0);
     391                 : #endif
     392                 :     }
     393                 : #endif
     394                 : #endif
     395               0 : }
     396                 : 
     397                 : #endif

Generated by: LCOV version 1.7