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.

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 }

mercurial