gfx/skia/trunk/src/core/SkFloat.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

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

mercurial