diff options
-rw-r--r-- | experimental/Intersection/SkAntiEdge.cpp | 8 | ||||
-rw-r--r-- | gyp/core.gypi | 2 | ||||
-rw-r--r-- | include/core/Sk64.h | 55 | ||||
-rw-r--r-- | include/core/SkFixed.h | 108 | ||||
-rw-r--r-- | include/utils/SkUnitMappers.h | 2 | ||||
-rw-r--r-- | src/core/Sk64.cpp | 54 | ||||
-rw-r--r-- | src/core/SkCordic.cpp | 289 | ||||
-rw-r--r-- | src/core/SkCordic.h | 28 | ||||
-rw-r--r-- | src/core/SkFloat.h | 2 | ||||
-rw-r--r-- | src/core/SkMath.cpp | 215 | ||||
-rw-r--r-- | src/core/SkMathPriv.h | 10 | ||||
-rw-r--r-- | src/core/SkPicturePlayback.cpp | 4 | ||||
-rw-r--r-- | src/effects/gradients/SkLinearGradient.cpp | 6 | ||||
-rw-r--r-- | src/utils/SkUnitMappers.cpp | 3 | ||||
-rw-r--r-- | tests/MathTest.cpp | 76 | ||||
-rw-r--r-- | tests/Sk64Test.cpp | 22 |
16 files changed, 26 insertions, 858 deletions
diff --git a/experimental/Intersection/SkAntiEdge.cpp b/experimental/Intersection/SkAntiEdge.cpp index 0aa159c53e..2cce960e52 100644 --- a/experimental/Intersection/SkAntiEdge.cpp +++ b/experimental/Intersection/SkAntiEdge.cpp @@ -7,6 +7,14 @@ #include "SkAntiEdge.h" #include "SkPoint.h" +/** Returns the signed fraction of a SkFixed + */ +static inline SkFixed SkFixedFraction(SkFixed x) +{ + SkFixed mask = x >> 31 << 16; + return (x & 0xFFFF) | mask; +} + void SkAntiEdge::pointOnLine(SkFixed x, SkFixed y) { float x0 = SkFixedToFloat(x); float y0 = SkFixedToFloat(y); diff --git a/gyp/core.gypi b/gyp/core.gypi index 84f2f511ec..d5c11534dc 100644 --- a/gyp/core.gypi +++ b/gyp/core.gypi @@ -59,8 +59,6 @@ '<(skia_src_path)/core/SkConfig8888.h', '<(skia_src_path)/core/SkConvolver.cpp', '<(skia_src_path)/core/SkConvolver.h', - '<(skia_src_path)/core/SkCordic.cpp', - '<(skia_src_path)/core/SkCordic.h', '<(skia_src_path)/core/SkCoreBlitters.h', '<(skia_src_path)/core/SkCubicClipper.cpp', '<(skia_src_path)/core/SkCubicClipper.h', diff --git a/include/core/Sk64.h b/include/core/Sk64.h index 6db3001fb5..eba8b684c6 100644 --- a/include/core/Sk64.h +++ b/include/core/Sk64.h @@ -10,7 +10,7 @@ #ifndef Sk64_DEFINED #define Sk64_DEFINED -#include "SkFixed.h" +#include "SkTypes.h" /** \class Sk64 @@ -28,33 +28,10 @@ struct SK_API Sk64 { */ SkBool is64() const { return fHi != ((int32_t)fLo >> 31); } - /** Returns non-zero if the Sk64 can be represented as a signed 48 bit integer. Used to know - if we can shift the value down by 16 to treat it as a SkFixed. - */ - SkBool isFixed() const; - /** Return the signed 32 bit integer equivalent. Asserts that is32() returns non-zero. */ int32_t get32() const { SkASSERT(this->is32()); return (int32_t)fLo; } - /** Return the number >> 16. Asserts that this does not loose any significant high bits. - */ - SkFixed getFixed() const { - SkASSERT(this->isFixed()); - - uint32_t sum = fLo + (1 << 15); - int32_t hi = fHi; - if (sum < fLo) { - hi += 1; - } - return (hi << 16) | (sum >> 16); - } - - /** Return the number >> 30. Asserts that this does not loose any - significant high bits. - */ - SkFract getFract() const; - /** Returns the square-root of the number as a signed 32 bit value. */ int32_t getSqrt() const; @@ -168,36 +145,6 @@ struct SK_API Sk64 { */ void div(int32_t, DivOptions); - /** return (this + other >> 16) as a 32bit result */ - SkFixed addGetFixed(const Sk64& other) const { - return this->addGetFixed(other.fHi, other.fLo); - } - - /** return (this + Sk64(hi, lo) >> 16) as a 32bit result */ - SkFixed addGetFixed(int32_t hi, uint32_t lo) const { -#ifdef SK_DEBUG - Sk64 tmp(*this); - tmp.add(hi, lo); -#endif - - uint32_t sum = fLo + lo; - hi += fHi + (sum < fLo); - lo = sum; - - sum = lo + (1 << 15); - if (sum < lo) - hi += 1; - - hi = (hi << 16) | (sum >> 16); - SkASSERT(hi == tmp.getFixed()); - return hi; - } - - /** Return the result of dividing the number by denom, treating the answer - as a SkFixed. (*this) << 16 / denom. It is an error for denom to be 0. - */ - SkFixed getFixedDiv(const Sk64& denom) const; - friend bool operator==(const Sk64& a, const Sk64& b) { return a.fHi == b.fHi && a.fLo == b.fLo; } diff --git a/include/core/SkFixed.h b/include/core/SkFixed.h index ea5e44c393..580d94b9ca 100644 --- a/include/core/SkFixed.h +++ b/include/core/SkFixed.h @@ -55,16 +55,6 @@ typedef int32_t SkFixed; #define SkFixedToDouble(x) ((x) * 1.5258789e-5) #define SkDoubleToFixed(x) ((SkFixed)((x) * SK_Fixed1)) -/** 32 bit signed integer used to represent fractions values with 30 bits to the right of the decimal point -*/ -typedef int32_t SkFract; -#define SK_Fract1 (1 << 30) -#define Sk_FracHalf (1 << 29) -#define SK_FractPIOver180 (0x11DF46A) - -#define SkFractToFloat(x) ((float)(x) * 0.00000000093132257f) -#define SkFloatToFract(x) ((SkFract)((x) * SK_Fract1)) - /** Converts an integer to a SkFixed, asserting that the result does not overflow a 32 bit signed integer */ @@ -79,31 +69,6 @@ typedef int32_t SkFract; #define SkIntToFixed(n) (SkFixed)((n) << 16) #endif -/** Converts a SkFixed to a SkFract, asserting that the result does not overflow - a 32 bit signed integer -*/ -#ifdef SK_DEBUG - inline SkFract SkFixedToFract(SkFixed x) - { - SkASSERT(x >= (-2 << 16) && x <= (2 << 16) - 1); - return x << 14; - } -#else - #define SkFixedToFract(x) ((x) << 14) -#endif - -/** Returns the signed fraction of a SkFixed -*/ -inline SkFixed SkFixedFraction(SkFixed x) -{ - SkFixed mask = x >> 31 << 16; - return (x & 0xFFFF) | mask; -} - -/** Converts a SkFract to a SkFixed -*/ -#define SkFractToFixed(x) ((x) >> 14) - #define SkFixedRoundToInt(x) (((x) + SK_FixedHalf) >> 16) #define SkFixedCeilToInt(x) (((x) + SK_Fixed1 - 1) >> 16) #define SkFixedFloorToInt(x) ((x) >> 16) @@ -121,7 +86,6 @@ inline SkFixed SkFixedFraction(SkFixed x) #define SkFixedAve(a, b) (((a) + (b)) >> 1) SkFixed SkFixedMul_portable(SkFixed, SkFixed); -SkFract SkFractMul_portable(SkFract, SkFract); inline SkFixed SkFixedSquare_portable(SkFixed value) { uint32_t a = SkAbs32(value); @@ -135,39 +99,18 @@ inline SkFixed SkFixedSquare_portable(SkFixed value) } #define SkFixedDiv(numer, denom) SkDivBits(numer, denom, 16) -SkFixed SkFixedDivInt(int32_t numer, int32_t denom); -SkFixed SkFixedMod(SkFixed numer, SkFixed denom); -#define SkFixedInvert(n) SkDivBits(SK_Fixed1, n, 16) -SkFixed SkFixedFastInvert(SkFixed n); -#define SkFixedSqrt(n) SkSqrtBits(n, 23) -SkFixed SkFixedMean(SkFixed a, SkFixed b); //*< returns sqrt(x*y) -int SkFixedMulCommon(SkFixed, int , int bias); // internal used by SkFixedMulFloor, SkFixedMulCeil, SkFixedMulRound -#define SkFractDiv(numer, denom) SkDivBits(numer, denom, 30) -#define SkFractSqrt(n) SkSqrtBits(n, 30) +/////////////////////////////////////////////////////////////////////////////// +// TODO: move fixed sin/cos into SkCosineMapper, as that is the only caller +// or rewrite SkCosineMapper to not use it at all SkFixed SkFixedSinCos(SkFixed radians, SkFixed* cosValueOrNull); #define SkFixedSin(radians) SkFixedSinCos(radians, NULL) -inline SkFixed SkFixedCos(SkFixed radians) -{ +static inline SkFixed SkFixedCos(SkFixed radians) { SkFixed cosValue; (void)SkFixedSinCos(radians, &cosValue); return cosValue; } -SkFixed SkFixedTan(SkFixed radians); -SkFixed SkFixedASin(SkFixed); -SkFixed SkFixedACos(SkFixed); -SkFixed SkFixedATan2(SkFixed y, SkFixed x); -SkFixed SkFixedExp(SkFixed); -SkFixed SkFixedLog(SkFixed); - -#define SK_FixedNearlyZero (SK_Fixed1 >> 12) - -inline bool SkFixedNearlyZero(SkFixed x, SkFixed tolerance = SK_FixedNearlyZero) -{ - SkASSERT(tolerance > 0); - return SkAbs32(x) < tolerance; -} ////////////////////////////////////////////////////////////////////////////////////////////////////// // Now look for ASM overrides for our portable versions (should consider putting this in its own file) @@ -177,16 +120,11 @@ inline bool SkFixedNearlyZero(SkFixed x, SkFixed tolerance = SK_FixedNearlyZero) { return (SkFixed)((SkLONGLONG)a * b >> 16); } - inline SkFract SkFractMul_longlong(SkFract a, SkFract b) - { - return (SkFract)((SkLONGLONG)a * b >> 30); - } inline SkFixed SkFixedSquare_longlong(SkFixed value) { return (SkFixed)((SkLONGLONG)value * value >> 16); } #define SkFixedMul(a,b) SkFixedMul_longlong(a,b) - #define SkFractMul(a,b) SkFractMul_longlong(a,b) #define SkFixedSquare(a) SkFixedSquare_longlong(a) #endif @@ -223,54 +161,16 @@ inline bool SkFixedNearlyZero(SkFixed x, SkFixed tolerance = SK_FixedNearlyZero) ); return x; } - inline SkFixed SkFixedMulAdd_arm(SkFixed x, SkFixed y, SkFixed a) - { - int32_t t; - asm("smull %0, %3, %1, %4 \n" - "add %0, %2, %0, lsr #16 \n" - "add %0, %0, %3, lsl #16 \n" - : "=r"(x), "=&r"(y), "=&r"(a), "=r"(t) - : "%r"(x), "1"(y), "2"(a) - : - ); - return x; - } - inline SkFixed SkFractMul_arm(SkFixed x, SkFixed y) - { - int32_t t; - asm("smull %0, %2, %1, %3 \n" - "mov %0, %0, lsr #30 \n" - "orr %0, %0, %2, lsl #2 \n" - : "=r"(x), "=&r"(y), "=r"(t) - : "r"(x), "1"(y) - : - ); - return x; - } #undef SkFixedMul - #undef SkFractMul #define SkFixedMul(x, y) SkFixedMul_arm(x, y) - #define SkFractMul(x, y) SkFractMul_arm(x, y) - #define SkFixedMulAdd(x, y, a) SkFixedMulAdd_arm(x, y, a) #undef SkFloatToFixed #define SkFloatToFixed(x) SkFloatToFixed_arm(x) #endif -/////////////////////// Now define our macros to the portable versions if they weren't overridden - -#ifndef SkFixedSquare - #define SkFixedSquare(x) SkFixedSquare_portable(x) -#endif #ifndef SkFixedMul #define SkFixedMul(x, y) SkFixedMul_portable(x, y) #endif -#ifndef SkFractMul - #define SkFractMul(x, y) SkFractMul_portable(x, y) -#endif -#ifndef SkFixedMulAdd - #define SkFixedMulAdd(x, y, a) (SkFixedMul(x, y) + (a)) -#endif /////////////////////////////////////////////////////////////////////////////// diff --git a/include/utils/SkUnitMappers.h b/include/utils/SkUnitMappers.h index 64aab5ddee..509e2d6380 100644 --- a/include/utils/SkUnitMappers.h +++ b/include/utils/SkUnitMappers.h @@ -28,7 +28,7 @@ protected: private: int fSegments; - SkFract fScale; // computed from fSegments + int32_t fScale; // computed from fSegments typedef SkUnitMapper INHERITED; }; diff --git a/src/core/Sk64.cpp b/src/core/Sk64.cpp index 54b30221c9..1fb0454ae2 100644 --- a/src/core/Sk64.cpp +++ b/src/core/Sk64.cpp @@ -133,19 +133,14 @@ void Sk64::abs() } } +#if 0 SkBool Sk64::isFixed() const { Sk64 tmp = *this; tmp.roundRight(16); return tmp.is32(); } - -SkFract Sk64::getFract() const -{ - Sk64 tmp = *this; - tmp.roundRight(30); - return tmp.get32(); -} +#endif void Sk64::sub(const Sk64& a) { @@ -298,48 +293,3 @@ int32_t Sk64::getSqrt() const return value | fLo; } #endif - -SkFixed Sk64::getFixedDiv(const Sk64& denom) const -{ - Sk64 N = *this; - Sk64 D = denom; - int32_t sign = SkExtractSign(N.fHi ^ D.fHi); - SkFixed result; - - N.abs(); - D.abs(); - - // need to knock D down to just 31 bits - // either by rounding it to the right, or shifting N to the left - // then we can just call 64/32 div - - int nclz = N.fHi ? SkCLZ(N.fHi) : 32; - int dclz = D.fHi ? SkCLZ(D.fHi) : (33 - (D.fLo >> 31)); - - int shiftN = nclz - 1; - SkASSERT(shiftN >= 0); - int shiftD = 33 - dclz; - SkASSERT(shiftD >= 0); - - if (shiftD + shiftN < 16) - shiftD = 16 - shiftN; - else - shiftN = 16 - shiftD; - - D.roundRight(shiftD); - if (D.isZero()) - result = SK_MaxS32; - else - { - if (shiftN >= 0) - N.shiftLeft(shiftN); - else - N.roundRight(-shiftN); - N.div(D.get32(), Sk64::kTrunc_DivOption); - if (N.is32()) - result = N.get32(); - else - result = SK_MaxS32; - } - return SkApplySign(result, sign); -} diff --git a/src/core/SkCordic.cpp b/src/core/SkCordic.cpp deleted file mode 100644 index 3adc92faa1..0000000000 --- a/src/core/SkCordic.cpp +++ /dev/null @@ -1,289 +0,0 @@ -/* - * Copyright 2006 The Android Open Source Project - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "SkCordic.h" -#include "SkMathPriv.h" -#include "Sk64.h" - -// 0x20000000 equals pi / 4 -const int32_t kATanDegrees[] = { 0x20000000, - 0x12E4051D, 0x9FB385B, 0x51111D4, 0x28B0D43, 0x145D7E1, 0xA2F61E, 0x517C55, - 0x28BE53, 0x145F2E, 0xA2F98, 0x517CC, 0x28BE6, 0x145F3, 0xA2F9, 0x517C, - 0x28BE, 0x145F, 0xA2F, 0x517, 0x28B, 0x145, 0xA2, 0x51, 0x28, 0x14, - 0xA, 0x5, 0x2, 0x1 }; - -const int32_t kFixedInvGain1 = 0x18bde0bb; // 0.607252935 - -static void SkCircularRotation(int32_t* x0, int32_t* y0, int32_t* z0) -{ - int32_t t = 0; - int32_t x = *x0; - int32_t y = *y0; - int32_t z = *z0; - const int32_t* tanPtr = kATanDegrees; - do { - int32_t x1 = y >> t; - int32_t y1 = x >> t; - int32_t tan = *tanPtr++; - if (z >= 0) { - x -= x1; - y += y1; - z -= tan; - } else { - x += x1; - y -= y1; - z += tan; - } - } while (++t < 16); // 30); - *x0 = x; - *y0 = y; - *z0 = z; -} - -SkFixed SkCordicSinCos(SkFixed radians, SkFixed* cosp) -{ - int32_t scaledRadians = radians * 0x28be; // scale radians to 65536 / PI() - int quadrant = scaledRadians >> 30; - quadrant += 1; - if (quadrant & 2) - scaledRadians = -scaledRadians + 0x80000000; - /* |a| <= 90 degrees as a 1.31 number */ - SkFixed sin = 0; - SkFixed cos = kFixedInvGain1; - SkCircularRotation(&cos, &sin, &scaledRadians); - Sk64 scaled; - scaled.setMul(sin, 0x6488d); - sin = scaled.fHi; - scaled.setMul(cos, 0x6488d); - if (quadrant & 2) - scaled.fHi = - scaled.fHi; - *cosp = scaled.fHi; - return sin; -} - -SkFixed SkCordicTan(SkFixed a) -{ - int32_t cos; - int32_t sin = SkCordicSinCos(a, &cos); - return SkFixedDiv(sin, cos); -} - -static int32_t SkCircularVector(int32_t* y0, int32_t* x0, int32_t vecMode) -{ - int32_t x = *x0; - int32_t y = *y0; - int32_t z = 0; - int32_t t = 0; - const int32_t* tanPtr = kATanDegrees; - do { - int32_t x1 = y >> t; - int32_t y1 = x >> t; - int32_t tan = *tanPtr++; - if (y < vecMode) { - x -= x1; - y += y1; - z -= tan; - } else { - x += x1; - y -= y1; - z += tan; - } - } while (++t < 16); // 30 - Sk64 scaled; - scaled.setMul(z, 0x6488d); // scale back into the SkScalar space (0x100000000/0x28be) - return scaled.fHi; -} - -SkFixed SkCordicASin(SkFixed a) { - int32_t sign = SkExtractSign(a); - int32_t z = SkFixedAbs(a); - if (z >= SK_Fixed1) - return SkApplySign(SK_FixedPI>>1, sign); - int32_t x = kFixedInvGain1; - int32_t y = 0; - z *= 0x28be; - z = SkCircularVector(&y, &x, z); - z = SkApplySign(z, ~sign); - return z; -} - -SkFixed SkCordicACos(SkFixed a) { - int32_t z = SkCordicASin(a); - z = (SK_FixedPI>>1) - z; - return z; -} - -SkFixed SkCordicATan2(SkFixed y, SkFixed x) { - if ((x | y) == 0) - return 0; - int32_t xsign = SkExtractSign(x); - x = SkFixedAbs(x); - int32_t result = SkCircularVector(&y, &x, 0); - if (xsign) { - int32_t rsign = SkExtractSign(result); - if (y == 0) - rsign = 0; - SkFixed pi = SkApplySign(SK_FixedPI, rsign); - result = pi - result; - } - return result; -} - -const int32_t kATanHDegrees[] = { - 0x1661788D, 0xA680D61, 0x51EA6FC, 0x28CBFDD, 0x1460E34, - 0xA2FCE8, 0x517D2E, 0x28BE6E, 0x145F32, - 0xA2F98, 0x517CC, 0x28BE6, 0x145F3, 0xA2F9, 0x517C, - 0x28BE, 0x145F, 0xA2F, 0x517, 0x28B, 0x145, 0xA2, 0x51, 0x28, 0x14, - 0xA, 0x5, 0x2, 0x1 }; - -const int32_t kFixedInvGain2 = 0x31330AAA; // 1.207534495 - -static void SkHyperbolic(int32_t* x0, int32_t* y0, int32_t* z0, int mode) -{ - int32_t t = 1; - int32_t x = *x0; - int32_t y = *y0; - int32_t z = *z0; - const int32_t* tanPtr = kATanHDegrees; - int k = -3; - do { - int32_t x1 = y >> t; - int32_t y1 = x >> t; - int32_t tan = *tanPtr++; - int count = 2 + (k >> 31); - if (++k == 1) - k = -2; - do { - if (((y >> 31) & mode) | ~((z >> 31) | mode)) { - x += x1; - y += y1; - z -= tan; - } else { - x -= x1; - y -= y1; - z += tan; - } - } while (--count); - } while (++t < 30); - *x0 = x; - *y0 = y; - *z0 = z; -} - -SkFixed SkCordicLog(SkFixed a) { - a *= 0x28be; - int32_t x = a + 0x28BE60DB; // 1.0 - int32_t y = a - 0x28BE60DB; - int32_t z = 0; - SkHyperbolic(&x, &y, &z, -1); - Sk64 scaled; - scaled.setMul(z, 0x6488d); - z = scaled.fHi; - return z << 1; -} - -SkFixed SkCordicExp(SkFixed a) { - int32_t cosh = kFixedInvGain2; - int32_t sinh = 0; - SkHyperbolic(&cosh, &sinh, &a, 0); - return cosh + sinh; -} - -#ifdef SK_DEBUG - -#include "SkFloatingPoint.h" - -void SkCordic_UnitTest() -{ -#if defined(SK_SUPPORT_UNITTEST) - float val; - for (float angle = -720; angle < 720; angle += 30) { - float radian = angle * 3.1415925358f / 180.0f; - SkFixed f_angle = SkFloatToFixed(radian); - // sincos - float sine = sinf(radian); - float cosine = cosf(radian); - SkFixed f_cosine; - SkFixed f_sine = SkCordicSinCos(f_angle, &f_cosine); - float sine2 = (float) f_sine / 65536.0f; - float cosine2 = (float) f_cosine / 65536.0f; - float error = fabsf(sine - sine2); - if (error > 0.001) - SkDebugf("sin error : angle = %g ; sin = %g ; cordic = %g\n", angle, sine, sine2); - error = fabsf(cosine - cosine2); - if (error > 0.001) - SkDebugf("cos error : angle = %g ; cos = %g ; cordic = %g\n", angle, cosine, cosine2); - // tan - float _tan = tanf(radian); - SkFixed f_tan = SkCordicTan(f_angle); - float tan2 = (float) f_tan / 65536.0f; - error = fabsf(_tan - tan2); - if (error > 0.05 && fabsf(_tan) < 1e6) - SkDebugf("tan error : angle = %g ; tan = %g ; cordic = %g\n", angle, _tan, tan2); - } - for (val = -1; val <= 1; val += .1f) { - SkFixed f_val = SkFloatToFixed(val); - // asin - float arcsine = asinf(val); - SkFixed f_arcsine = SkCordicASin(f_val); - float arcsine2 = (float) f_arcsine / 65536.0f; - float error = fabsf(arcsine - arcsine2); - if (error > 0.001) - SkDebugf("asin error : val = %g ; asin = %g ; cordic = %g\n", val, arcsine, arcsine2); - } -#if 1 - for (val = -1; val <= 1; val += .1f) { -#else - val = .5; { -#endif - SkFixed f_val = SkFloatToFixed(val); - // acos - float arccos = acosf(val); - SkFixed f_arccos = SkCordicACos(f_val); - float arccos2 = (float) f_arccos / 65536.0f; - float error = fabsf(arccos - arccos2); - if (error > 0.001) - SkDebugf("acos error : val = %g ; acos = %g ; cordic = %g\n", val, arccos, arccos2); - } - // atan2 -#if 1 - for (val = -1000; val <= 1000; val += 500.f) { - for (float val2 = -1000; val2 <= 1000; val2 += 500.f) { -#else - val = 0; { - float val2 = -1000; { -#endif - SkFixed f_val = SkFloatToFixed(val); - SkFixed f_val2 = SkFloatToFixed(val2); - float arctan = atan2f(val, val2); - SkFixed f_arctan = SkCordicATan2(f_val, f_val2); - float arctan2 = (float) f_arctan / 65536.0f; - float error = fabsf(arctan - arctan2); - if (error > 0.001) - SkDebugf("atan2 error : val = %g ; val2 = %g ; atan2 = %g ; cordic = %g\n", val, val2, arctan, arctan2); - } - } - // log -#if 1 - for (val = 0.125f; val <= 8.f; val *= 2.0f) { -#else - val = .5; { -#endif - SkFixed f_val = SkFloatToFixed(val); - // acos - float log = logf(val); - SkFixed f_log = SkCordicLog(f_val); - float log2 = (float) f_log / 65536.0f; - float error = fabsf(log - log2); - if (error > 0.001) - SkDebugf("log error : val = %g ; log = %g ; cordic = %g\n", val, log, log2); - } - // exp -#endif -} - -#endif diff --git a/src/core/SkCordic.h b/src/core/SkCordic.h deleted file mode 100644 index fecf645643..0000000000 --- a/src/core/SkCordic.h +++ /dev/null @@ -1,28 +0,0 @@ - -/* - * Copyright 2006 The Android Open Source Project - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - - -#ifndef SkCordic_DEFINED -#define SkCordic_DEFINED - -#include "SkTypes.h" -#include "SkFixed.h" - -SkFixed SkCordicACos(SkFixed a); -SkFixed SkCordicASin(SkFixed a); -SkFixed SkCordicATan2(SkFixed y, SkFixed x); -SkFixed SkCordicExp(SkFixed a); -SkFixed SkCordicLog(SkFixed a); -SkFixed SkCordicSinCos(SkFixed radians, SkFixed* cosp); -SkFixed SkCordicTan(SkFixed a); - -#ifdef SK_DEBUG - void SkCordic_UnitTest(); -#endif - -#endif // SkCordic diff --git a/src/core/SkFloat.h b/src/core/SkFloat.h index 74cd19e542..0d4f9b41a7 100644 --- a/src/core/SkFloat.h +++ b/src/core/SkFloat.h @@ -20,12 +20,10 @@ public: // void setShift(int value, int shift) { fPacked = SetShift(value, shift); } void setInt(int value) { fPacked = SetShift(value, 0); } void setFixed(SkFixed value) { fPacked = SetShift(value, -16); } - void setFract(SkFract value) { fPacked = SetShift(value, -30); } // int getShift(int shift) const { return GetShift(fPacked, shift); } int getInt() const { return GetShift(fPacked, 0); } SkFixed getFixed() const { return GetShift(fPacked, -16); } - SkFract getFract() const { return GetShift(fPacked, -30); } void abs() { fPacked = Abs(fPacked); } void negate() { fPacked = Neg(fPacked); } diff --git a/src/core/SkMath.cpp b/src/core/SkMath.cpp index f1ba3a3a0c..1d356c7951 100644 --- a/src/core/SkMath.cpp +++ b/src/core/SkMath.cpp @@ -6,7 +6,6 @@ */ #include "SkMathPriv.h" -#include "SkCordic.h" #include "SkFloatBits.h" #include "SkFloatingPoint.h" #include "Sk64.h" @@ -54,63 +53,8 @@ int32_t SkMulDiv(int32_t numer1, int32_t numer2, int32_t denom) { return tmp.get32(); } -int32_t SkMulShift(int32_t a, int32_t b, unsigned shift) { - int sign = SkExtractSign(a ^ b); - - if (shift > 63) { - return sign; - } - - a = SkAbs32(a); - b = SkAbs32(b); - - uint32_t ah = a >> 16; - uint32_t al = a & 0xFFFF; - uint32_t bh = b >> 16; - uint32_t bl = b & 0xFFFF; - - uint32_t A = ah * bh; - uint32_t B = ah * bl + al * bh; - uint32_t C = al * bl; - - /* [ A ] - [ B ] - [ C ] - */ - uint32_t lo = C + (B << 16); - int32_t hi = A + (B >> 16) + (lo < C); - - if (sign < 0) { - hi = -hi - Sk32ToBool(lo); - lo = 0 - lo; - } - - if (shift == 0) { -#ifdef SK_DEBUGx - SkASSERT(((int32_t)lo >> 31) == hi); -#endif - return lo; - } else if (shift >= 32) { - return hi >> (shift - 32); - } else { -#ifdef SK_DEBUGx - int32_t tmp = hi >> shift; - SkASSERT(tmp == 0 || tmp == -1); -#endif - // we want (hi << (32 - shift)) | (lo >> shift) but rounded - int roundBit = (lo >> (shift - 1)) & 1; - return ((hi << (32 - shift)) | (lo >> shift)) + roundBit; - } -} - SkFixed SkFixedMul_portable(SkFixed a, SkFixed b) { -#if 0 - Sk64 tmp; - - tmp.setMul(a, b); - tmp.shiftRight(16); - return tmp.fLo; -#elif defined(SkLONGLONG) +#if defined(SkLONGLONG) return static_cast<SkFixed>((SkLONGLONG)a * b >> 16); #else int sa = SkExtractSign(a); @@ -130,103 +74,6 @@ SkFixed SkFixedMul_portable(SkFixed a, SkFixed b) { #endif } -SkFract SkFractMul_portable(SkFract a, SkFract b) { -#if 0 - Sk64 tmp; - tmp.setMul(a, b); - return tmp.getFract(); -#elif defined(SkLONGLONG) - return static_cast<SkFract>((SkLONGLONG)a * b >> 30); -#else - int sa = SkExtractSign(a); - int sb = SkExtractSign(b); - // now make them positive - a = SkApplySign(a, sa); - b = SkApplySign(b, sb); - - uint32_t ah = a >> 16; - uint32_t al = a & 0xFFFF; - uint32_t bh = b >> 16; - uint32_t bl = b & 0xFFFF; - - uint32_t A = ah * bh; - uint32_t B = ah * bl + al * bh; - uint32_t C = al * bl; - - /* [ A ] - [ B ] - [ C ] - */ - uint32_t Lo = C + (B << 16); - uint32_t Hi = A + (B >>16) + (Lo < C); - - SkASSERT((Hi >> 29) == 0); // else overflow - - int32_t R = (Hi << 2) + (Lo >> 30); - - return SkApplySign(R, sa ^ sb); -#endif -} - -int SkFixedMulCommon(SkFixed a, int b, int bias) { - // this function only works if b is 16bits - SkASSERT(b == (int16_t)b); - SkASSERT(b >= 0); - - int sa = SkExtractSign(a); - a = SkApplySign(a, sa); - uint32_t ah = a >> 16; - uint32_t al = a & 0xFFFF; - uint32_t R = ah * b + ((al * b + bias) >> 16); - return SkApplySign(R, sa); -} - -#ifdef SK_DEBUGx - #define TEST_FASTINVERT -#endif - -SkFixed SkFixedFastInvert(SkFixed x) { -/* Adapted (stolen) from gglRecip() -*/ - - if (x == SK_Fixed1) { - return SK_Fixed1; - } - - int sign = SkExtractSign(x); - uint32_t a = SkApplySign(x, sign); - - if (a <= 2) { - return SkApplySign(SK_MaxS32, sign); - } - -#ifdef TEST_FASTINVERT - SkFixed orig = a; - uint32_t slow = SkFixedDiv(SK_Fixed1, a); -#endif - - // normalize a - int lz = SkCLZ(a); - a = a << lz >> 16; - - // compute 1/a approximation (0.5 <= a < 1.0) - uint32_t r = 0x17400 - a; // (2.90625 (~2.914) - 2*a) >> 1 - - // Newton-Raphson iteration: - // x = r*(2 - a*r) = ((r/2)*(1 - a*r/2))*4 - r = ( (0x10000 - ((a*r)>>16)) * r ) >> 15; - r = ( (0x10000 - ((a*r)>>16)) * r ) >> (30 - lz); - -#ifdef TEST_FASTINVERT - SkDebugf("SkFixedFastInvert(%x %g) = %x %g Slow[%x %g]\n", - orig, orig/65536., - r, r/65536., - slow, slow/65536.); -#endif - - return SkApplySign(r, sign); -} - /////////////////////////////////////////////////////////////////////////////// #define DIVBITS_ITER(n) \ @@ -295,26 +142,6 @@ int32_t SkDivBits(int32_t numer, int32_t denom, int shift_bias) { return SkApplySign(result, sign); } -/* mod(float numer, float denom) seems to always return the sign - of the numer, so that's what we do too -*/ -SkFixed SkFixedMod(SkFixed numer, SkFixed denom) { - int sn = SkExtractSign(numer); - int sd = SkExtractSign(denom); - - numer = SkApplySign(numer, sn); - denom = SkApplySign(denom, sd); - - if (numer < denom) { - return SkApplySign(numer, sn); - } else if (numer == denom) { - return 0; - } else { - SkFixed div = SkFixedDiv(numer, denom); - return SkApplySign(SkFixedMul(denom, div & 0xFFFF), sn); - } -} - /* www.worldserver.com/turk/computergraphics/FixedSqrt.pdf */ int32_t SkSqrtBits(int32_t x, int count) { @@ -340,38 +167,6 @@ int32_t SkSqrtBits(int32_t x, int count) { return root; } -int32_t SkCubeRootBits(int32_t value, int bits) { - SkASSERT(bits > 0); - - int sign = SkExtractSign(value); - value = SkApplySign(value, sign); - - uint32_t root = 0; - uint32_t curr = (uint32_t)value >> 30; - value <<= 2; - - do { - root <<= 1; - uint32_t guess = root * root + root; - guess = (guess << 1) + guess; // guess *= 3 - if (guess < curr) { - curr -= guess + 1; - root |= 1; - } - curr = (curr << 3) | ((uint32_t)value >> 29); - value <<= 3; - } while (--bits); - - return SkApplySign(root, sign); -} - -SkFixed SkFixedMean(SkFixed a, SkFixed b) { - Sk64 tmp; - - tmp.setMul(a, b); - return tmp.getSqrt(); -} - /////////////////////////////////////////////////////////////////////////////// float SkScalarSinCos(float radians, float* cosValue) { @@ -503,11 +298,3 @@ SkFixed SkFixedSinCos(SkFixed radians, SkFixed* cosValuePtr) { return sinValue; } -/////////////////////////////////////////////////////////////////////////////// - -SkFixed SkFixedTan(SkFixed radians) { return SkCordicTan(radians); } -SkFixed SkFixedASin(SkFixed x) { return SkCordicASin(x); } -SkFixed SkFixedACos(SkFixed x) { return SkCordicACos(x); } -SkFixed SkFixedATan2(SkFixed y, SkFixed x) { return SkCordicATan2(y, x); } -SkFixed SkFixedExp(SkFixed x) { return SkCordicExp(x); } -SkFixed SkFixedLog(SkFixed x) { return SkCordicLog(x); } diff --git a/src/core/SkMathPriv.h b/src/core/SkMathPriv.h index 4eaad8b9b1..f93ab61078 100644 --- a/src/core/SkMathPriv.h +++ b/src/core/SkMathPriv.h @@ -39,16 +39,6 @@ static inline unsigned SkClampUMax(unsigned value, unsigned max) { return value; } -/** Computes the 64bit product of a * b, and then shifts the answer down by - shift bits, returning the low 32bits. shift must be [0..63] - e.g. to perform a fixedmul, call SkMulShift(a, b, 16) - */ -int32_t SkMulShift(int32_t a, int32_t b, unsigned shift); - -/** Return the integer cube root of value, with a bias of bitBias - */ -int32_t SkCubeRootBits(int32_t value, int bitBias); - /////////////////////////////////////////////////////////////////////////////// /** Return a*b/255, truncating away any fractional bits. Only valid if both diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp index 82c7a03bcd..cb73689eeb 100644 --- a/src/core/SkPicturePlayback.cpp +++ b/src/core/SkPicturePlayback.cpp @@ -1217,11 +1217,11 @@ void dumpMatrix(const SkMatrix& matrix) const { SkScalar perspX = matrix.getPerspX(); if (perspX != defaultMatrix.getPerspX()) bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), - "{kPerspX, %g}, ", SkFractToFloat(perspX)); + "{kPerspX, %g}, ", perspX); SkScalar perspY = matrix.getPerspY(); if (perspY != defaultMatrix.getPerspY()) bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), - "{kPerspY, %g}, ", SkFractToFloat(perspY)); + "{kPerspY, %g}, ", perspY); SkDebugf("%s{0}};\n", pBuffer); } diff --git a/src/effects/gradients/SkLinearGradient.cpp b/src/effects/gradients/SkLinearGradient.cpp index 5563a03f7e..70452962ac 100644 --- a/src/effects/gradients/SkLinearGradient.cpp +++ b/src/effects/gradients/SkLinearGradient.cpp @@ -377,6 +377,10 @@ void shadeSpan16_linear_repeat(TileProc proc, SkFixed dx, SkFixed fx, } } +static bool fixed_nearly_zero(SkFixed x) { + return SkAbs32(x) < (SK_Fixed1 >> 12); +} + void SkLinearGradient::shadeSpan16(int x, int y, uint16_t* SK_RESTRICT dstC, int count) { SkASSERT(count > 0); @@ -402,7 +406,7 @@ void SkLinearGradient::shadeSpan16(int x, int y, } LinearShade16Proc shadeProc = shadeSpan16_linear_repeat; - if (SkFixedNearlyZero(dx)) { + if (fixed_nearly_zero(dx)) { shadeProc = shadeSpan16_linear_vertical; } else if (SkShader::kClamp_TileMode == fTileMode) { shadeProc = shadeSpan16_linear_clamp; diff --git a/src/utils/SkUnitMappers.cpp b/src/utils/SkUnitMappers.cpp index 5976e9de52..f86a4542db 100644 --- a/src/utils/SkUnitMappers.cpp +++ b/src/utils/SkUnitMappers.cpp @@ -8,6 +8,7 @@ #include "SkUnitMappers.h" #include "SkFlattenableBuffers.h" + SkDiscreteMapper::SkDiscreteMapper(int segments) { if (segments < 2) { fSegments = 0; @@ -17,7 +18,7 @@ SkDiscreteMapper::SkDiscreteMapper(int segments) { segments = 0xFFFF; } fSegments = segments; - fScale = SK_Fract1 / (segments - 1); + fScale = (1 << 30) / (segments - 1); } } diff --git a/tests/MathTest.cpp b/tests/MathTest.cpp index d6649542c2..1b8954a361 100644 --- a/tests/MathTest.cpp +++ b/tests/MathTest.cpp @@ -427,7 +427,6 @@ static void test_copysign(skiatest::Reporter* reporter) { DEF_TEST(Math, reporter) { int i; - int32_t x; SkRandom rand; // these should assert @@ -459,30 +458,6 @@ DEF_TEST(Math, reporter) { REPORTER_ASSERT(reporter, SkScalarIsNaN(x)); } - for (i = 1; i <= 10; i++) { - x = SkCubeRootBits(i*i*i, 11); - REPORTER_ASSERT(reporter, x == i); - } - - x = SkFixedSqrt(SK_Fixed1); - REPORTER_ASSERT(reporter, x == SK_Fixed1); - x = SkFixedSqrt(SK_Fixed1/4); - REPORTER_ASSERT(reporter, x == SK_Fixed1/2); - x = SkFixedSqrt(SK_Fixed1*4); - REPORTER_ASSERT(reporter, x == SK_Fixed1*2); - - x = SkFractSqrt(SK_Fract1); - REPORTER_ASSERT(reporter, x == SK_Fract1); - x = SkFractSqrt(SK_Fract1/4); - REPORTER_ASSERT(reporter, x == SK_Fract1/2); - x = SkFractSqrt(SK_Fract1/16); - REPORTER_ASSERT(reporter, x == SK_Fract1/4); - - for (i = 1; i < 100; i++) { - x = SkFixedSqrt(SK_Fixed1 * i * i); - REPORTER_ASSERT(reporter, x == SK_Fixed1 * i); - } - for (i = 0; i < 1000; i++) { int value = rand.nextS16(); int max = rand.nextU16(); @@ -535,17 +510,6 @@ DEF_TEST(Math, reporter) { } REPORTER_ASSERT(reporter, result == (int32_t)check); - result = SkFractDiv(numer, denom); - check = ((SkLONGLONG)numer << 30) / denom; - - REPORTER_ASSERT(reporter, result != (SkFixed)SK_NaN32); - if (check > SK_MaxS32) { - check = SK_MaxS32; - } else if (check < -SK_MaxS32) { - check = SK_MinS32; - } - REPORTER_ASSERT(reporter, result == (int32_t)check); - // make them <= 2^24, so we don't overflow in fixmul numer = numer << 8 >> 8; denom = denom << 8 >> 8; @@ -557,49 +521,9 @@ DEF_TEST(Math, reporter) { result = SkFixedMul(numer, numer); r2 = SkFixedSquare(numer); REPORTER_ASSERT(reporter, result == r2); - - if (numer >= 0 && denom >= 0) { - SkFixed mean = SkFixedMean(numer, denom); - float prod = SkFixedToFloat(numer) * SkFixedToFloat(denom); - float fm = sk_float_sqrt(sk_float_abs(prod)); - SkFixed mean2 = SkFloatToFixed(fm); - int diff = SkAbs32(mean - mean2); - REPORTER_ASSERT(reporter, diff <= 1); - } - - { - SkFixed mod = SkFixedMod(numer, denom); - float n = SkFixedToFloat(numer); - float d = SkFixedToFloat(denom); - float m = sk_float_mod(n, d); - // ensure the same sign - REPORTER_ASSERT(reporter, mod == 0 || (mod < 0) == (m < 0)); - int diff = SkAbs32(mod - SkFloatToFixed(m)); - REPORTER_ASSERT(reporter, (diff >> 7) == 0); - } } #endif - for (i = 0; i < 10000; i++) { - SkFract x = rand.nextU() >> 1; - double xx = (double)x / SK_Fract1; - SkFract xr = SkFractSqrt(x); - SkFract check = SkFloatToFract(sqrt(xx)); - REPORTER_ASSERT(reporter, xr == check || - xr == check-1 || - xr == check+1); - - xr = SkFixedSqrt(x); - xx = (double)x / SK_Fixed1; - check = SkFloatToFixed(sqrt(xx)); - REPORTER_ASSERT(reporter, xr == check || xr == check-1); - - xr = SkSqrt32(x); - xx = (double)x; - check = (int32_t)sqrt(xx); - REPORTER_ASSERT(reporter, xr == check || xr == check-1); - } - test_blend(reporter); if (false) test_floor(reporter); diff --git a/tests/Sk64Test.cpp b/tests/Sk64Test.cpp index 9af32b14be..589801b272 100644 --- a/tests/Sk64Test.cpp +++ b/tests/Sk64Test.cpp @@ -174,28 +174,6 @@ DEF_TEST(Sk64Test, reporter) { int32_t ck = (int32_t)sqrt((double)wide.getLongLong()); int diff = denom - ck; REPORTER_ASSERT(reporter, SkAbs32(diff) <= 1); - - wide.setMul(rand.nextS(), rand.nextS()); - Sk64 dwide; - dwide.setMul(rand.nextS(), rand.nextS()); - SkFixed fixdiv = wide.getFixedDiv(dwide); - double dnumer = (double)wide.getLongLong(); - double ddenom = (double)dwide.getLongLong(); - double ddiv = dnumer / ddenom; - SkFixed dfixdiv; - if (ddiv >= (double)SK_MaxS32 / (double)SK_Fixed1) - dfixdiv = SK_MaxS32; - else if (ddiv <= -(double)SK_MaxS32 / (double)SK_Fixed1) - dfixdiv = SK_MinS32; - else - dfixdiv = SkFloatToFixed(dnumer / ddenom); - diff = fixdiv - dfixdiv; - - if (SkAbs32(diff) > 1) { - SkDebugf(" %d === numer %g denom %g div %g xdiv %x fxdiv %x\n", - i, dnumer, ddenom, ddiv, dfixdiv, fixdiv); - } - REPORTER_ASSERT(reporter, SkAbs32(diff) <= 1); } #endif } |