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.

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

mercurial