gfx/skia/trunk/src/core/SkMath.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.

     1 /*
     2  * Copyright 2008 The Android Open Source Project
     3  *
     4  * Use of this source code is governed by a BSD-style license that can be
     5  * found in the LICENSE file.
     6  */
     8 #include "SkMathPriv.h"
     9 #include "SkFloatBits.h"
    10 #include "SkFloatingPoint.h"
    11 #include "SkScalar.h"
    13 const uint32_t gIEEENotANumber = 0x7FFFFFFF;
    14 const uint32_t gIEEEInfinity = 0x7F800000;
    15 const uint32_t gIEEENegativeInfinity = 0xFF800000;
    17 #define sub_shift(zeros, x, n)  \
    18     zeros -= n;                 \
    19     x >>= n
    21 int SkCLZ_portable(uint32_t x) {
    22     if (x == 0) {
    23         return 32;
    24     }
    26     int zeros = 31;
    27     if (x & 0xFFFF0000) {
    28         sub_shift(zeros, x, 16);
    29     }
    30     if (x & 0xFF00) {
    31         sub_shift(zeros, x, 8);
    32     }
    33     if (x & 0xF0) {
    34         sub_shift(zeros, x, 4);
    35     }
    36     if (x & 0xC) {
    37         sub_shift(zeros, x, 2);
    38     }
    39     if (x & 0x2) {
    40         sub_shift(zeros, x, 1);
    41     }
    43     return zeros;
    44 }
    46 int32_t SkMulDiv(int32_t numer1, int32_t numer2, int32_t denom) {
    47     SkASSERT(denom);
    49     int64_t tmp = sk_64_mul(numer1, numer2) / denom;
    50     return sk_64_asS32(tmp);
    51 }
    53 SkFixed SkFixedMul_portable(SkFixed a, SkFixed b) {
    54 #if defined(SkLONGLONG)
    55     return static_cast<SkFixed>((int64_t)a * b >> 16);
    56 #else
    57     int sa = SkExtractSign(a);
    58     int sb = SkExtractSign(b);
    59     // now make them positive
    60     a = SkApplySign(a, sa);
    61     b = SkApplySign(b, sb);
    63     uint32_t    ah = a >> 16;
    64     uint32_t    al = a & 0xFFFF;
    65     uint32_t bh = b >> 16;
    66     uint32_t bl = b & 0xFFFF;
    68     uint32_t R = ah * b + al * bh + (al * bl >> 16);
    70     return SkApplySign(R, sa ^ sb);
    71 #endif
    72 }
    74 ///////////////////////////////////////////////////////////////////////////////
    76 #define DIVBITS_ITER(n)                                 \
    77     case n:                                             \
    78         if ((numer = (numer << 1) - denom) >= 0)        \
    79             result |= 1 << (n - 1); else numer += denom
    81 int32_t SkDivBits(int32_t numer, int32_t denom, int shift_bias) {
    82     SkASSERT(denom != 0);
    83     if (numer == 0) {
    84         return 0;
    85     }
    87     // make numer and denom positive, and sign hold the resulting sign
    88     int32_t sign = SkExtractSign(numer ^ denom);
    89     numer = SkAbs32(numer);
    90     denom = SkAbs32(denom);
    92     int nbits = SkCLZ(numer) - 1;
    93     int dbits = SkCLZ(denom) - 1;
    94     int bits = shift_bias - nbits + dbits;
    96     if (bits < 0) {  // answer will underflow
    97         return 0;
    98     }
    99     if (bits > 31) {  // answer will overflow
   100         return SkApplySign(SK_MaxS32, sign);
   101     }
   103     denom <<= dbits;
   104     numer <<= nbits;
   106     SkFixed result = 0;
   108     // do the first one
   109     if ((numer -= denom) >= 0) {
   110         result = 1;
   111     } else {
   112         numer += denom;
   113     }
   115     // Now fall into our switch statement if there are more bits to compute
   116     if (bits > 0) {
   117         // make room for the rest of the answer bits
   118         result <<= bits;
   119         switch (bits) {
   120             DIVBITS_ITER(31); DIVBITS_ITER(30); DIVBITS_ITER(29);
   121             DIVBITS_ITER(28); DIVBITS_ITER(27); DIVBITS_ITER(26);
   122             DIVBITS_ITER(25); DIVBITS_ITER(24); DIVBITS_ITER(23);
   123             DIVBITS_ITER(22); DIVBITS_ITER(21); DIVBITS_ITER(20);
   124             DIVBITS_ITER(19); DIVBITS_ITER(18); DIVBITS_ITER(17);
   125             DIVBITS_ITER(16); DIVBITS_ITER(15); DIVBITS_ITER(14);
   126             DIVBITS_ITER(13); DIVBITS_ITER(12); DIVBITS_ITER(11);
   127             DIVBITS_ITER(10); DIVBITS_ITER( 9); DIVBITS_ITER( 8);
   128             DIVBITS_ITER( 7); DIVBITS_ITER( 6); DIVBITS_ITER( 5);
   129             DIVBITS_ITER( 4); DIVBITS_ITER( 3); DIVBITS_ITER( 2);
   130             // we merge these last two together, makes GCC make better ARM
   131             default:
   132             DIVBITS_ITER( 1);
   133         }
   134     }
   136     if (result < 0) {
   137         result = SK_MaxS32;
   138     }
   139     return SkApplySign(result, sign);
   140 }
   142 /* www.worldserver.com/turk/computergraphics/FixedSqrt.pdf
   143 */
   144 int32_t SkSqrtBits(int32_t x, int count) {
   145     SkASSERT(x >= 0 && count > 0 && (unsigned)count <= 30);
   147     uint32_t    root = 0;
   148     uint32_t    remHi = 0;
   149     uint32_t    remLo = x;
   151     do {
   152         root <<= 1;
   154         remHi = (remHi<<2) | (remLo>>30);
   155         remLo <<= 2;
   157         uint32_t testDiv = (root << 1) + 1;
   158         if (remHi >= testDiv) {
   159             remHi -= testDiv;
   160             root++;
   161         }
   162     } while (--count >= 0);
   164     return root;
   165 }
   167 ///////////////////////////////////////////////////////////////////////////////
   169 float SkScalarSinCos(float radians, float* cosValue) {
   170     float sinValue = sk_float_sin(radians);
   172     if (cosValue) {
   173         *cosValue = sk_float_cos(radians);
   174         if (SkScalarNearlyZero(*cosValue)) {
   175             *cosValue = 0;
   176         }
   177     }
   179     if (SkScalarNearlyZero(sinValue)) {
   180         sinValue = 0;
   181     }
   182     return sinValue;
   183 }
   185 #define INTERP_SINTABLE
   186 #define BUILD_TABLE_AT_RUNTIMEx
   188 #define kTableSize  256
   190 #ifdef BUILD_TABLE_AT_RUNTIME
   191     static uint16_t gSkSinTable[kTableSize];
   193     static void build_sintable(uint16_t table[]) {
   194         for (int i = 0; i < kTableSize; i++) {
   195             double  rad = i * 3.141592653589793 / (2*kTableSize);
   196             double  val = sin(rad);
   197             int     ival = (int)(val * SK_Fixed1);
   198             table[i] = SkToU16(ival);
   199         }
   200     }
   201 #else
   202     #include "SkSinTable.h"
   203 #endif
   205 #define SK_Fract1024SizeOver2PI     0x28BE60    /* floatToFract(1024 / 2PI) */
   207 #ifdef INTERP_SINTABLE
   208 static SkFixed interp_table(const uint16_t table[], int index, int partial255) {
   209     SkASSERT((unsigned)index < kTableSize);
   210     SkASSERT((unsigned)partial255 <= 255);
   212     SkFixed lower = table[index];
   213     SkFixed upper = (index == kTableSize - 1) ? SK_Fixed1 : table[index + 1];
   215     SkASSERT(lower < upper);
   216     SkASSERT(lower >= 0);
   217     SkASSERT(upper <= SK_Fixed1);
   219     partial255 += (partial255 >> 7);
   220     return lower + ((upper - lower) * partial255 >> 8);
   221 }
   222 #endif
   224 SkFixed SkFixedSinCos(SkFixed radians, SkFixed* cosValuePtr) {
   225     SkASSERT(SK_ARRAY_COUNT(gSkSinTable) == kTableSize);
   227 #ifdef BUILD_TABLE_AT_RUNTIME
   228     static bool gFirstTime = true;
   229     if (gFirstTime) {
   230         build_sintable(gSinTable);
   231         gFirstTime = false;
   232     }
   233 #endif
   235     // make radians positive
   236     SkFixed sinValue, cosValue;
   237     int32_t cosSign = 0;
   238     int32_t sinSign = SkExtractSign(radians);
   239     radians = SkApplySign(radians, sinSign);
   240     // scale it to 0...1023 ...
   242 #ifdef INTERP_SINTABLE
   243     radians = SkMulDiv(radians, 2 * kTableSize * 256, SK_FixedPI);
   244     int findex = radians & (kTableSize * 256 - 1);
   245     int index = findex >> 8;
   246     int partial = findex & 255;
   247     sinValue = interp_table(gSkSinTable, index, partial);
   249     findex = kTableSize * 256 - findex - 1;
   250     index = findex >> 8;
   251     partial = findex & 255;
   252     cosValue = interp_table(gSkSinTable, index, partial);
   254     int quad = ((unsigned)radians / (kTableSize * 256)) & 3;
   255 #else
   256     radians = SkMulDiv(radians, 2 * kTableSize, SK_FixedPI);
   257     int     index = radians & (kTableSize - 1);
   259     if (index == 0) {
   260         sinValue = 0;
   261         cosValue = SK_Fixed1;
   262     } else {
   263         sinValue = gSkSinTable[index];
   264         cosValue = gSkSinTable[kTableSize - index];
   265     }
   266     int quad = ((unsigned)radians / kTableSize) & 3;
   267 #endif
   269     if (quad & 1) {
   270         SkTSwap<SkFixed>(sinValue, cosValue);
   271     }
   272     if (quad & 2) {
   273         sinSign = ~sinSign;
   274     }
   275     if (((quad - 1) & 2) == 0) {
   276         cosSign = ~cosSign;
   277     }
   279     // restore the sign for negative angles
   280     sinValue = SkApplySign(sinValue, sinSign);
   281     cosValue = SkApplySign(cosValue, cosSign);
   283 #ifdef SK_DEBUG
   284     if (1) {
   285         SkFixed sin2 = SkFixedMul(sinValue, sinValue);
   286         SkFixed cos2 = SkFixedMul(cosValue, cosValue);
   287         int diff = cos2 + sin2 - SK_Fixed1;
   288         SkASSERT(SkAbs32(diff) <= 7);
   289     }
   290 #endif
   292     if (cosValuePtr) {
   293         *cosValuePtr = cosValue;
   294     }
   295     return sinValue;
   296 }

mercurial