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