remove unused SkFixed and SkFract functions
BUG= R=caryclark@google.com Review URL: https://codereview.chromium.org/113873008 git-svn-id: http://skia.googlecode.com/svn/trunk@12767 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
4fa237f2fb
commit
1915fd09f3
@ -7,6 +7,14 @@
|
|||||||
#include "SkAntiEdge.h"
|
#include "SkAntiEdge.h"
|
||||||
#include "SkPoint.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) {
|
void SkAntiEdge::pointOnLine(SkFixed x, SkFixed y) {
|
||||||
float x0 = SkFixedToFloat(x);
|
float x0 = SkFixedToFloat(x);
|
||||||
float y0 = SkFixedToFloat(y);
|
float y0 = SkFixedToFloat(y);
|
||||||
|
@ -59,8 +59,6 @@
|
|||||||
'<(skia_src_path)/core/SkConfig8888.h',
|
'<(skia_src_path)/core/SkConfig8888.h',
|
||||||
'<(skia_src_path)/core/SkConvolver.cpp',
|
'<(skia_src_path)/core/SkConvolver.cpp',
|
||||||
'<(skia_src_path)/core/SkConvolver.h',
|
'<(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/SkCoreBlitters.h',
|
||||||
'<(skia_src_path)/core/SkCubicClipper.cpp',
|
'<(skia_src_path)/core/SkCubicClipper.cpp',
|
||||||
'<(skia_src_path)/core/SkCubicClipper.h',
|
'<(skia_src_path)/core/SkCubicClipper.h',
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#ifndef Sk64_DEFINED
|
#ifndef Sk64_DEFINED
|
||||||
#define Sk64_DEFINED
|
#define Sk64_DEFINED
|
||||||
|
|
||||||
#include "SkFixed.h"
|
#include "SkTypes.h"
|
||||||
|
|
||||||
/** \class Sk64
|
/** \class Sk64
|
||||||
|
|
||||||
@ -28,33 +28,10 @@ struct SK_API Sk64 {
|
|||||||
*/
|
*/
|
||||||
SkBool is64() const { return fHi != ((int32_t)fLo >> 31); }
|
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.
|
/** Return the signed 32 bit integer equivalent. Asserts that is32() returns non-zero.
|
||||||
*/
|
*/
|
||||||
int32_t get32() const { SkASSERT(this->is32()); return (int32_t)fLo; }
|
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. */
|
/** Returns the square-root of the number as a signed 32 bit value. */
|
||||||
int32_t getSqrt() const;
|
int32_t getSqrt() const;
|
||||||
|
|
||||||
@ -168,36 +145,6 @@ struct SK_API Sk64 {
|
|||||||
*/
|
*/
|
||||||
void div(int32_t, DivOptions);
|
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) {
|
friend bool operator==(const Sk64& a, const Sk64& b) {
|
||||||
return a.fHi == b.fHi && a.fLo == b.fLo;
|
return a.fHi == b.fHi && a.fLo == b.fLo;
|
||||||
}
|
}
|
||||||
|
@ -55,16 +55,6 @@ typedef int32_t SkFixed;
|
|||||||
#define SkFixedToDouble(x) ((x) * 1.5258789e-5)
|
#define SkFixedToDouble(x) ((x) * 1.5258789e-5)
|
||||||
#define SkDoubleToFixed(x) ((SkFixed)((x) * SK_Fixed1))
|
#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
|
/** Converts an integer to a SkFixed, asserting that the result does not overflow
|
||||||
a 32 bit signed integer
|
a 32 bit signed integer
|
||||||
*/
|
*/
|
||||||
@ -79,31 +69,6 @@ typedef int32_t SkFract;
|
|||||||
#define SkIntToFixed(n) (SkFixed)((n) << 16)
|
#define SkIntToFixed(n) (SkFixed)((n) << 16)
|
||||||
#endif
|
#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 SkFixedRoundToInt(x) (((x) + SK_FixedHalf) >> 16)
|
||||||
#define SkFixedCeilToInt(x) (((x) + SK_Fixed1 - 1) >> 16)
|
#define SkFixedCeilToInt(x) (((x) + SK_Fixed1 - 1) >> 16)
|
||||||
#define SkFixedFloorToInt(x) ((x) >> 16)
|
#define SkFixedFloorToInt(x) ((x) >> 16)
|
||||||
@ -121,7 +86,6 @@ inline SkFixed SkFixedFraction(SkFixed x)
|
|||||||
#define SkFixedAve(a, b) (((a) + (b)) >> 1)
|
#define SkFixedAve(a, b) (((a) + (b)) >> 1)
|
||||||
|
|
||||||
SkFixed SkFixedMul_portable(SkFixed, SkFixed);
|
SkFixed SkFixedMul_portable(SkFixed, SkFixed);
|
||||||
SkFract SkFractMul_portable(SkFract, SkFract);
|
|
||||||
inline SkFixed SkFixedSquare_portable(SkFixed value)
|
inline SkFixed SkFixedSquare_portable(SkFixed value)
|
||||||
{
|
{
|
||||||
uint32_t a = SkAbs32(value);
|
uint32_t a = SkAbs32(value);
|
||||||
@ -135,39 +99,18 @@ inline SkFixed SkFixedSquare_portable(SkFixed value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define SkFixedDiv(numer, denom) SkDivBits(numer, denom, 16)
|
#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);
|
SkFixed SkFixedSinCos(SkFixed radians, SkFixed* cosValueOrNull);
|
||||||
#define SkFixedSin(radians) SkFixedSinCos(radians, NULL)
|
#define SkFixedSin(radians) SkFixedSinCos(radians, NULL)
|
||||||
inline SkFixed SkFixedCos(SkFixed radians)
|
static inline SkFixed SkFixedCos(SkFixed radians) {
|
||||||
{
|
|
||||||
SkFixed cosValue;
|
SkFixed cosValue;
|
||||||
(void)SkFixedSinCos(radians, &cosValue);
|
(void)SkFixedSinCos(radians, &cosValue);
|
||||||
return 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)
|
// 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);
|
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)
|
inline SkFixed SkFixedSquare_longlong(SkFixed value)
|
||||||
{
|
{
|
||||||
return (SkFixed)((SkLONGLONG)value * value >> 16);
|
return (SkFixed)((SkLONGLONG)value * value >> 16);
|
||||||
}
|
}
|
||||||
#define SkFixedMul(a,b) SkFixedMul_longlong(a,b)
|
#define SkFixedMul(a,b) SkFixedMul_longlong(a,b)
|
||||||
#define SkFractMul(a,b) SkFractMul_longlong(a,b)
|
|
||||||
#define SkFixedSquare(a) SkFixedSquare_longlong(a)
|
#define SkFixedSquare(a) SkFixedSquare_longlong(a)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -223,54 +161,16 @@ inline bool SkFixedNearlyZero(SkFixed x, SkFixed tolerance = SK_FixedNearlyZero)
|
|||||||
);
|
);
|
||||||
return x;
|
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 SkFixedMul
|
||||||
#undef SkFractMul
|
|
||||||
#define SkFixedMul(x, y) SkFixedMul_arm(x, y)
|
#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
|
#undef SkFloatToFixed
|
||||||
#define SkFloatToFixed(x) SkFloatToFixed_arm(x)
|
#define SkFloatToFixed(x) SkFloatToFixed_arm(x)
|
||||||
#endif
|
#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
|
#ifndef SkFixedMul
|
||||||
#define SkFixedMul(x, y) SkFixedMul_portable(x, y)
|
#define SkFixedMul(x, y) SkFixedMul_portable(x, y)
|
||||||
#endif
|
#endif
|
||||||
#ifndef SkFractMul
|
|
||||||
#define SkFractMul(x, y) SkFractMul_portable(x, y)
|
|
||||||
#endif
|
|
||||||
#ifndef SkFixedMulAdd
|
|
||||||
#define SkFixedMulAdd(x, y, a) (SkFixedMul(x, y) + (a))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
int fSegments;
|
int fSegments;
|
||||||
SkFract fScale; // computed from fSegments
|
int32_t fScale; // computed from fSegments
|
||||||
|
|
||||||
typedef SkUnitMapper INHERITED;
|
typedef SkUnitMapper INHERITED;
|
||||||
};
|
};
|
||||||
|
@ -133,19 +133,14 @@ void Sk64::abs()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
SkBool Sk64::isFixed() const
|
SkBool Sk64::isFixed() const
|
||||||
{
|
{
|
||||||
Sk64 tmp = *this;
|
Sk64 tmp = *this;
|
||||||
tmp.roundRight(16);
|
tmp.roundRight(16);
|
||||||
return tmp.is32();
|
return tmp.is32();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
SkFract Sk64::getFract() const
|
|
||||||
{
|
|
||||||
Sk64 tmp = *this;
|
|
||||||
tmp.roundRight(30);
|
|
||||||
return tmp.get32();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Sk64::sub(const Sk64& a)
|
void Sk64::sub(const Sk64& a)
|
||||||
{
|
{
|
||||||
@ -298,48 +293,3 @@ int32_t Sk64::getSqrt() const
|
|||||||
return value | fLo;
|
return value | fLo;
|
||||||
}
|
}
|
||||||
#endif
|
#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);
|
|
||||||
}
|
|
||||||
|
@ -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
|
|
@ -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
|
|
@ -20,12 +20,10 @@ public:
|
|||||||
// void setShift(int value, int shift) { fPacked = SetShift(value, shift); }
|
// void setShift(int value, int shift) { fPacked = SetShift(value, shift); }
|
||||||
void setInt(int value) { fPacked = SetShift(value, 0); }
|
void setInt(int value) { fPacked = SetShift(value, 0); }
|
||||||
void setFixed(SkFixed value) { fPacked = SetShift(value, -16); }
|
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 getShift(int shift) const { return GetShift(fPacked, shift); }
|
||||||
int getInt() const { return GetShift(fPacked, 0); }
|
int getInt() const { return GetShift(fPacked, 0); }
|
||||||
SkFixed getFixed() const { return GetShift(fPacked, -16); }
|
SkFixed getFixed() const { return GetShift(fPacked, -16); }
|
||||||
SkFract getFract() const { return GetShift(fPacked, -30); }
|
|
||||||
|
|
||||||
void abs() { fPacked = Abs(fPacked); }
|
void abs() { fPacked = Abs(fPacked); }
|
||||||
void negate() { fPacked = Neg(fPacked); }
|
void negate() { fPacked = Neg(fPacked); }
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "SkMathPriv.h"
|
#include "SkMathPriv.h"
|
||||||
#include "SkCordic.h"
|
|
||||||
#include "SkFloatBits.h"
|
#include "SkFloatBits.h"
|
||||||
#include "SkFloatingPoint.h"
|
#include "SkFloatingPoint.h"
|
||||||
#include "Sk64.h"
|
#include "Sk64.h"
|
||||||
@ -54,63 +53,8 @@ int32_t SkMulDiv(int32_t numer1, int32_t numer2, int32_t denom) {
|
|||||||
return tmp.get32();
|
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) {
|
SkFixed SkFixedMul_portable(SkFixed a, SkFixed b) {
|
||||||
#if 0
|
#if defined(SkLONGLONG)
|
||||||
Sk64 tmp;
|
|
||||||
|
|
||||||
tmp.setMul(a, b);
|
|
||||||
tmp.shiftRight(16);
|
|
||||||
return tmp.fLo;
|
|
||||||
#elif defined(SkLONGLONG)
|
|
||||||
return static_cast<SkFixed>((SkLONGLONG)a * b >> 16);
|
return static_cast<SkFixed>((SkLONGLONG)a * b >> 16);
|
||||||
#else
|
#else
|
||||||
int sa = SkExtractSign(a);
|
int sa = SkExtractSign(a);
|
||||||
@ -130,103 +74,6 @@ SkFixed SkFixedMul_portable(SkFixed a, SkFixed b) {
|
|||||||
#endif
|
#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) \
|
#define DIVBITS_ITER(n) \
|
||||||
@ -295,26 +142,6 @@ int32_t SkDivBits(int32_t numer, int32_t denom, int shift_bias) {
|
|||||||
return SkApplySign(result, sign);
|
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
|
/* www.worldserver.com/turk/computergraphics/FixedSqrt.pdf
|
||||||
*/
|
*/
|
||||||
int32_t SkSqrtBits(int32_t x, int count) {
|
int32_t SkSqrtBits(int32_t x, int count) {
|
||||||
@ -340,38 +167,6 @@ int32_t SkSqrtBits(int32_t x, int count) {
|
|||||||
return root;
|
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) {
|
float SkScalarSinCos(float radians, float* cosValue) {
|
||||||
@ -503,11 +298,3 @@ SkFixed SkFixedSinCos(SkFixed radians, SkFixed* cosValuePtr) {
|
|||||||
return sinValue;
|
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); }
|
|
||||||
|
@ -39,16 +39,6 @@ static inline unsigned SkClampUMax(unsigned value, unsigned max) {
|
|||||||
return value;
|
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
|
/** Return a*b/255, truncating away any fractional bits. Only valid if both
|
||||||
|
@ -1217,11 +1217,11 @@ void dumpMatrix(const SkMatrix& matrix) const {
|
|||||||
SkScalar perspX = matrix.getPerspX();
|
SkScalar perspX = matrix.getPerspX();
|
||||||
if (perspX != defaultMatrix.getPerspX())
|
if (perspX != defaultMatrix.getPerspX())
|
||||||
bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
|
bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
|
||||||
"{kPerspX, %g}, ", SkFractToFloat(perspX));
|
"{kPerspX, %g}, ", perspX);
|
||||||
SkScalar perspY = matrix.getPerspY();
|
SkScalar perspY = matrix.getPerspY();
|
||||||
if (perspY != defaultMatrix.getPerspY())
|
if (perspY != defaultMatrix.getPerspY())
|
||||||
bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
|
bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
|
||||||
"{kPerspY, %g}, ", SkFractToFloat(perspY));
|
"{kPerspY, %g}, ", perspY);
|
||||||
SkDebugf("%s{0}};\n", pBuffer);
|
SkDebugf("%s{0}};\n", pBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
void SkLinearGradient::shadeSpan16(int x, int y,
|
||||||
uint16_t* SK_RESTRICT dstC, int count) {
|
uint16_t* SK_RESTRICT dstC, int count) {
|
||||||
SkASSERT(count > 0);
|
SkASSERT(count > 0);
|
||||||
@ -402,7 +406,7 @@ void SkLinearGradient::shadeSpan16(int x, int y,
|
|||||||
}
|
}
|
||||||
|
|
||||||
LinearShade16Proc shadeProc = shadeSpan16_linear_repeat;
|
LinearShade16Proc shadeProc = shadeSpan16_linear_repeat;
|
||||||
if (SkFixedNearlyZero(dx)) {
|
if (fixed_nearly_zero(dx)) {
|
||||||
shadeProc = shadeSpan16_linear_vertical;
|
shadeProc = shadeSpan16_linear_vertical;
|
||||||
} else if (SkShader::kClamp_TileMode == fTileMode) {
|
} else if (SkShader::kClamp_TileMode == fTileMode) {
|
||||||
shadeProc = shadeSpan16_linear_clamp;
|
shadeProc = shadeSpan16_linear_clamp;
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "SkUnitMappers.h"
|
#include "SkUnitMappers.h"
|
||||||
#include "SkFlattenableBuffers.h"
|
#include "SkFlattenableBuffers.h"
|
||||||
|
|
||||||
|
|
||||||
SkDiscreteMapper::SkDiscreteMapper(int segments) {
|
SkDiscreteMapper::SkDiscreteMapper(int segments) {
|
||||||
if (segments < 2) {
|
if (segments < 2) {
|
||||||
fSegments = 0;
|
fSegments = 0;
|
||||||
@ -17,7 +18,7 @@ SkDiscreteMapper::SkDiscreteMapper(int segments) {
|
|||||||
segments = 0xFFFF;
|
segments = 0xFFFF;
|
||||||
}
|
}
|
||||||
fSegments = segments;
|
fSegments = segments;
|
||||||
fScale = SK_Fract1 / (segments - 1);
|
fScale = (1 << 30) / (segments - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -427,7 +427,6 @@ static void test_copysign(skiatest::Reporter* reporter) {
|
|||||||
|
|
||||||
DEF_TEST(Math, reporter) {
|
DEF_TEST(Math, reporter) {
|
||||||
int i;
|
int i;
|
||||||
int32_t x;
|
|
||||||
SkRandom rand;
|
SkRandom rand;
|
||||||
|
|
||||||
// these should assert
|
// these should assert
|
||||||
@ -459,30 +458,6 @@ DEF_TEST(Math, reporter) {
|
|||||||
REPORTER_ASSERT(reporter, SkScalarIsNaN(x));
|
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++) {
|
for (i = 0; i < 1000; i++) {
|
||||||
int value = rand.nextS16();
|
int value = rand.nextS16();
|
||||||
int max = rand.nextU16();
|
int max = rand.nextU16();
|
||||||
@ -535,17 +510,6 @@ DEF_TEST(Math, reporter) {
|
|||||||
}
|
}
|
||||||
REPORTER_ASSERT(reporter, result == (int32_t)check);
|
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
|
// make them <= 2^24, so we don't overflow in fixmul
|
||||||
numer = numer << 8 >> 8;
|
numer = numer << 8 >> 8;
|
||||||
denom = denom << 8 >> 8;
|
denom = denom << 8 >> 8;
|
||||||
@ -557,49 +521,9 @@ DEF_TEST(Math, reporter) {
|
|||||||
result = SkFixedMul(numer, numer);
|
result = SkFixedMul(numer, numer);
|
||||||
r2 = SkFixedSquare(numer);
|
r2 = SkFixedSquare(numer);
|
||||||
REPORTER_ASSERT(reporter, result == r2);
|
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
|
#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);
|
test_blend(reporter);
|
||||||
|
|
||||||
if (false) test_floor(reporter);
|
if (false) test_floor(reporter);
|
||||||
|
@ -174,28 +174,6 @@ DEF_TEST(Sk64Test, reporter) {
|
|||||||
int32_t ck = (int32_t)sqrt((double)wide.getLongLong());
|
int32_t ck = (int32_t)sqrt((double)wide.getLongLong());
|
||||||
int diff = denom - ck;
|
int diff = denom - ck;
|
||||||
REPORTER_ASSERT(reporter, SkAbs32(diff) <= 1);
|
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
|
#endif
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user