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:
commit-bot@chromium.org 2013-08-14 11:43:52 +00:00
Родитель 2dc8b96230
Коммит 73ab296536
8 изменённых файлов: 23 добавлений и 252 удалений

Просмотреть файл

@ -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"