зеркало из https://github.com/mozilla/moz-skia.git
ARM Skia NEON patches - 04 - Clean SkFixed / SkLONGLONG
It removes SkLONGLONG and uses int64_t to implement the SkFixed operations for which a SkLONGLONG version existed. It also removes the 32 bit version that are being replaced. BUG= R=djsollen@google.com, reed@google.com Author: kevin.petit.arm@gmail.com Review URL: https://chromiumcodereview.appspot.com/18539004 git-svn-id: http://skia.googlecode.com/svn/trunk@10705 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
Родитель
2dc8b96230
Коммит
73ab296536
|
@ -103,13 +103,6 @@
|
|||
//#define SK_UINT8_BITFIELD_BENDIAN
|
||||
//#define SK_UINT8_BITFIELD_LENDIAN
|
||||
|
||||
|
||||
/* Some compilers don't support long long for 64bit integers. If yours does
|
||||
not, define this to the appropriate type.
|
||||
*/
|
||||
//#define SkLONGLONG int64_t
|
||||
|
||||
|
||||
/* To write debug messages to a console, skia will call SkDebugf(...) following
|
||||
printf conventions (e.g. const char* format, ...). If you want to redirect
|
||||
this to something other than printf, define yours here
|
||||
|
|
|
@ -221,10 +221,6 @@ struct SK_API Sk64 {
|
|||
friend bool operator>=(const Sk64& a, const Sk64& b) {
|
||||
return a.fHi > b.fHi || (a.fHi == b.fHi && a.fLo >= b.fLo);
|
||||
}
|
||||
|
||||
#ifdef SkLONGLONG
|
||||
SkLONGLONG getLongLong() const;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -120,20 +120,6 @@ inline SkFixed SkFixedFraction(SkFixed x)
|
|||
#define SkFixedAbs(x) SkAbs32(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);
|
||||
uint32_t ah = a >> 16;
|
||||
uint32_t al = a & 0xFFFF;
|
||||
SkFixed result = ah * a + al * ah + (al * al >> 16);
|
||||
if (result >= 0)
|
||||
return result;
|
||||
else // Overflow.
|
||||
return SK_FixedMax;
|
||||
}
|
||||
|
||||
#define SkFixedDiv(numer, denom) SkDivBits(numer, denom, 16)
|
||||
SkFixed SkFixedDivInt(int32_t numer, int32_t denom);
|
||||
SkFixed SkFixedMod(SkFixed numer, SkFixed denom);
|
||||
|
@ -169,27 +155,28 @@ inline bool SkFixedNearlyZero(SkFixed x, SkFixed tolerance = SK_FixedNearlyZero)
|
|||
return SkAbs32(x) < tolerance;
|
||||
}
|
||||
|
||||
inline SkFixed SkFixedMul_longlong(SkFixed a, SkFixed b)
|
||||
{
|
||||
return (SkFixed)((int64_t)a * b >> 16);
|
||||
}
|
||||
|
||||
inline SkFract SkFractMul_longlong(SkFract a, SkFract b)
|
||||
{
|
||||
return (SkFract)((int64_t)a * b >> 30);
|
||||
}
|
||||
|
||||
inline SkFixed SkFixedSquare_longlong(SkFixed value)
|
||||
{
|
||||
return (SkFixed)((int64_t)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)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Now look for ASM overrides for our portable versions (should consider putting this in its own file)
|
||||
|
||||
#ifdef SkLONGLONG
|
||||
inline SkFixed SkFixedMul_longlong(SkFixed a, SkFixed b)
|
||||
{
|
||||
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
|
||||
|
||||
#if defined(SK_CPU_ARM)
|
||||
/* This guy does not handle NaN or other obscurities, but is faster than
|
||||
than (int)(x*65536)
|
||||
|
@ -262,12 +249,6 @@ inline bool SkFixedNearlyZero(SkFixed x, SkFixed tolerance = SK_FixedNearlyZero)
|
|||
#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
|
||||
|
|
|
@ -269,17 +269,6 @@
|
|||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(SK_BUILD_FOR_WIN32) || defined(SK_BUILD_FOR_MAC)
|
||||
#ifndef SkLONGLONG
|
||||
#ifdef SK_BUILD_FOR_WIN32
|
||||
#define SkLONGLONG __int64
|
||||
#else
|
||||
#define SkLONGLONG long long
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef SK_BUILD_FOR_WINCE
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
|
|
@ -299,15 +299,6 @@ int32_t Sk64::getSqrt() const
|
|||
return root;
|
||||
}
|
||||
|
||||
#ifdef SkLONGLONG
|
||||
SkLONGLONG Sk64::getLongLong() const
|
||||
{
|
||||
SkLONGLONG value = fHi;
|
||||
value <<= 32;
|
||||
return value | fLo;
|
||||
}
|
||||
#endif
|
||||
|
||||
SkFixed Sk64::getFixedDiv(const Sk64& denom) const
|
||||
{
|
||||
Sk64 N = *this;
|
||||
|
|
|
@ -105,71 +105,6 @@ int32_t SkMulShift(int32_t a, int32_t b, unsigned shift) {
|
|||
}
|
||||
}
|
||||
|
||||
SkFixed SkFixedMul_portable(SkFixed a, SkFixed b) {
|
||||
#if 0
|
||||
Sk64 tmp;
|
||||
|
||||
tmp.setMul(a, b);
|
||||
tmp.shiftRight(16);
|
||||
return tmp.fLo;
|
||||
#elif defined(SkLONGLONG)
|
||||
return static_cast<SkFixed>((SkLONGLONG)a * b >> 16);
|
||||
#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 R = ah * b + al * bh + (al * bl >> 16);
|
||||
|
||||
return SkApplySign(R, sa ^ sb);
|
||||
#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);
|
||||
|
|
|
@ -186,7 +186,6 @@ static void test_blend(skiatest::Reporter* reporter) {
|
|||
}
|
||||
}
|
||||
|
||||
#if defined(SkLONGLONG)
|
||||
static int symmetric_fixmul(int a, int b) {
|
||||
int sa = SkExtractSign(a);
|
||||
int sb = SkExtractSign(b);
|
||||
|
@ -195,18 +194,17 @@ static int symmetric_fixmul(int a, int b) {
|
|||
b = SkApplySign(b, sb);
|
||||
|
||||
#if 1
|
||||
int c = (int)(((SkLONGLONG)a * b) >> 16);
|
||||
int c = (int)(((int64_t)a * b) >> 16);
|
||||
|
||||
return SkApplySign(c, sa ^ sb);
|
||||
#else
|
||||
SkLONGLONG ab = (SkLONGLONG)a * b;
|
||||
int64_t ab = (int64_t)a * b;
|
||||
if (sa ^ sb) {
|
||||
ab = -ab;
|
||||
}
|
||||
return ab >> 16;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
static void check_length(skiatest::Reporter* reporter,
|
||||
const SkPoint& p, SkScalar targetLen) {
|
||||
|
@ -522,12 +520,11 @@ static void TestMath(skiatest::Reporter* reporter) {
|
|||
unittest_fastfloat(reporter);
|
||||
unittest_isfinite(reporter);
|
||||
|
||||
#ifdef SkLONGLONG
|
||||
for (i = 0; i < 10000; i++) {
|
||||
SkFixed numer = rand.nextS();
|
||||
SkFixed denom = rand.nextS();
|
||||
SkFixed result = SkFixedDiv(numer, denom);
|
||||
SkLONGLONG check = ((SkLONGLONG)numer << 16) / denom;
|
||||
int64_t check = ((int64_t)numer << 16) / denom;
|
||||
|
||||
(void)SkCLZ(numer);
|
||||
(void)SkCLZ(denom);
|
||||
|
@ -541,7 +538,7 @@ static void TestMath(skiatest::Reporter* reporter) {
|
|||
REPORTER_ASSERT(reporter, result == (int32_t)check);
|
||||
|
||||
result = SkFractDiv(numer, denom);
|
||||
check = ((SkLONGLONG)numer << 30) / denom;
|
||||
check = ((int64_t)numer << 30) / denom;
|
||||
|
||||
REPORTER_ASSERT(reporter, result != (SkFixed)SK_NaN32);
|
||||
if (check > SK_MaxS32) {
|
||||
|
@ -583,7 +580,6 @@ static void TestMath(skiatest::Reporter* reporter) {
|
|||
REPORTER_ASSERT(reporter, (diff >> 7) == 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; i < 10000; i++) {
|
||||
SkFract x = rand.nextU() >> 1;
|
||||
|
|
|
@ -24,13 +24,6 @@ static void bool_table_test(skiatest::Reporter* reporter,
|
|||
REPORTER_ASSERT(reporter, a.getSign() == table.sign);
|
||||
}
|
||||
|
||||
#ifdef SkLONGLONG
|
||||
static SkLONGLONG asLL(const Sk64& a)
|
||||
{
|
||||
return ((SkLONGLONG)a.fHi << 32) | a.fLo;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void TestSk64(skiatest::Reporter* reporter) {
|
||||
enum BoolTests {
|
||||
kZero_BoolTest,
|
||||
|
@ -94,109 +87,6 @@ static void TestSk64(skiatest::Reporter* reporter) {
|
|||
c = a; c.sub(b);
|
||||
REPORTER_ASSERT(reporter, c.get32() == aa - bb);
|
||||
}
|
||||
|
||||
#ifdef SkLONGLONG
|
||||
for (i = 0; i < 1000; i++)
|
||||
{
|
||||
rand.next64(&a); //a.fHi >>= 1; // avoid overflow
|
||||
rand.next64(&b); //b.fHi >>= 1; // avoid overflow
|
||||
|
||||
if (!(i & 3)) // want to explicitly test these cases
|
||||
{
|
||||
a.fLo = 0;
|
||||
b.fLo = 0;
|
||||
}
|
||||
else if (!(i & 7)) // want to explicitly test these cases
|
||||
{
|
||||
a.fHi = 0;
|
||||
b.fHi = 0;
|
||||
}
|
||||
|
||||
SkLONGLONG aa = asLL(a);
|
||||
SkLONGLONG bb = asLL(b);
|
||||
|
||||
REPORTER_ASSERT(reporter, (a < b) == (aa < bb));
|
||||
REPORTER_ASSERT(reporter, (a <= b) == (aa <= bb));
|
||||
REPORTER_ASSERT(reporter, (a > b) == (aa > bb));
|
||||
REPORTER_ASSERT(reporter, (a >= b) == (aa >= bb));
|
||||
REPORTER_ASSERT(reporter, (a == b) == (aa == bb));
|
||||
REPORTER_ASSERT(reporter, (a != b) == (aa != bb));
|
||||
|
||||
c = a; c.add(b);
|
||||
REPORTER_ASSERT(reporter, asLL(c) == aa + bb);
|
||||
c = a; c.sub(b);
|
||||
REPORTER_ASSERT(reporter, asLL(c) == aa - bb);
|
||||
c = a; c.rsub(b);
|
||||
REPORTER_ASSERT(reporter, asLL(c) == bb - aa);
|
||||
c = a; c.negate();
|
||||
REPORTER_ASSERT(reporter, asLL(c) == -aa);
|
||||
|
||||
int bits = rand.nextU() & 63;
|
||||
c = a; c.shiftLeft(bits);
|
||||
REPORTER_ASSERT(reporter, asLL(c) == (aa << bits));
|
||||
c = a; c.shiftRight(bits);
|
||||
REPORTER_ASSERT(reporter, asLL(c) == (aa >> bits));
|
||||
c = a; c.roundRight(bits);
|
||||
|
||||
SkLONGLONG tmp;
|
||||
|
||||
tmp = aa;
|
||||
if (bits > 0)
|
||||
tmp += (SkLONGLONG)1 << (bits - 1);
|
||||
REPORTER_ASSERT(reporter, asLL(c) == (tmp >> bits));
|
||||
|
||||
c.setMul(a.fHi, b.fHi);
|
||||
tmp = (SkLONGLONG)a.fHi * b.fHi;
|
||||
REPORTER_ASSERT(reporter, asLL(c) == tmp);
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < 100000; i++)
|
||||
{
|
||||
Sk64 wide;
|
||||
int32_t denom = rand.nextS();
|
||||
|
||||
while (denom == 0)
|
||||
denom = rand.nextS();
|
||||
wide.setMul(rand.nextS(), rand.nextS());
|
||||
SkLONGLONG check = wide.getLongLong();
|
||||
|
||||
wide.div(denom, Sk64::kTrunc_DivOption);
|
||||
check /= denom;
|
||||
SkLONGLONG w = wide.getLongLong();
|
||||
|
||||
REPORTER_ASSERT(reporter, check == w);
|
||||
|
||||
wide.setMul(rand.nextS(), rand.nextS());
|
||||
wide.abs();
|
||||
denom = wide.getSqrt();
|
||||
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
|
||||
}
|
||||
|
||||
#include "TestClassDef.h"
|
||||
|
|
Загрузка…
Ссылка в новой задаче