diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-01-09 17:51:21 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-01-09 17:51:21 -0800 |
commit | 03202c9c3dfbf8c4feb0a1ee9b3680817e633f58 (patch) | |
tree | 1d0ba7cbf3e77c239527697ac455312b216c434e /include/core/SkFixed.h | |
parent | 37df15a82319228ae28fe5d99c010b288aad7091 (diff) | |
download | external_skia-03202c9c3dfbf8c4feb0a1ee9b3680817e633f58.zip external_skia-03202c9c3dfbf8c4feb0a1ee9b3680817e633f58.tar.gz external_skia-03202c9c3dfbf8c4feb0a1ee9b3680817e633f58.tar.bz2 |
auto import from //branches/cupcake/...@125939
Diffstat (limited to 'include/core/SkFixed.h')
-rw-r--r-- | include/core/SkFixed.h | 253 |
1 files changed, 253 insertions, 0 deletions
diff --git a/include/core/SkFixed.h b/include/core/SkFixed.h new file mode 100644 index 0000000..be4bf99 --- /dev/null +++ b/include/core/SkFixed.h @@ -0,0 +1,253 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SkFixed_DEFINED +#define SkFixed_DEFINED + +#include "SkTypes.h" + +/** \file SkFixed.h + + Types and macros for 16.16 fixed point +*/ + +/** 32 bit signed integer used to represent fractions values with 16 bits to the right of the decimal point +*/ +typedef int32_t SkFixed; +#define SK_Fixed1 (1 << 16) +#define SK_FixedHalf (1 << 15) +#define SK_FixedMax (0x7FFFFFFF) +#define SK_FixedMin (0x1) +#define SK_FixedNaN ((int) 0x80000000) +#define SK_FixedPI (0x3243F) +#define SK_FixedSqrt2 (92682) +#define SK_FixedTanPIOver8 (0x6A0A) +#define SK_FixedRoot2Over2 (0xB505) + +#ifdef SK_CAN_USE_FLOAT + #define SkFixedToFloat(x) ((x) * 1.5258789e-5f) + #define SkFloatToFixed(x) ((SkFixed)((x) * SK_Fixed1)) + + #define SkFixedToDouble(x) ((x) * 1.5258789e-5) + #define SkDoubleToFixed(x) ((SkFixed)((x) * SK_Fixed1)) +#endif + +/** 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) + +#ifdef SK_CAN_USE_FLOAT + #define SkFractToFloat(x) ((float)(x) * 0.00000000093132257f) + #define SkFloatToFract(x) ((SkFract)((x) * SK_Fract1)) +#endif + +/** Converts an integer to a SkFixed, asserting that the result does not overflow + a 32 bit signed integer +*/ +#ifdef SK_DEBUG + inline SkFixed SkIntToFixed(int n) + { + SkASSERT(n >= -32768 && n <= 32767); + return n << 16; + } +#else + // force the cast to SkFixed to ensure that the answer is signed (like the debug version) + #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) +/** Round a SkFixed to an integer +*/ +#define SkFixedRound(x) (((x) + SK_FixedHalf) >> 16) +#define SkFixedCeil(x) (((x) + SK_Fixed1 - 1) >> 16) +#define SkFixedFloor(x) ((x) >> 16) +#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; + return ah * a + al * ah + (al * al >> 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) + +SkFixed SkFixedSinCos(SkFixed radians, SkFixed* cosValueOrNull); +#define SkFixedSin(radians) SkFixedSinCos(radians, NULL) +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) + +#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 (SkFixed)((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(__arm__) && !defined(__thumb__) + /* This guy does not handle NaN or other obscurities, but is faster than + than (int)(x*65536) when we only have software floats + */ + inline SkFixed SkFloatToFixed_arm(float x) + { + register int32_t y, z; + asm("movs %1, %3, lsl #1 \n" + "mov %2, #0x8E \n" + "sub %1, %2, %1, lsr #24 \n" + "mov %2, %3, lsl #8 \n" + "orr %2, %2, #0x80000000 \n" + "mov %1, %2, lsr %1 \n" + "rsbcs %1, %1, #0 \n" + : "=r"(x), "=&r"(y), "=&r"(z) + : "r"(x) + : "cc" + ); + return y; + } + inline SkFixed SkFixedMul_arm(SkFixed x, SkFixed y) + { + register int32_t t; + asm("smull %0, %2, %1, %3 \n" + "mov %0, %0, lsr #16 \n" + "orr %0, %0, %2, lsl #16 \n" + : "=r"(x), "=&r"(y), "=r"(t) + : "r"(x), "1"(y) + : + ); + return x; + } + inline SkFixed SkFixedMulAdd_arm(SkFixed x, SkFixed y, SkFixed a) + { + register 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) + { + register 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 + +#endif |