/* libs/opengles/fp.h ** ** Copyright 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 ANDROID_OPENGLES_FP_H #define ANDROID_OPENGLES_FP_H #include <stdint.h> #include <stddef.h> #include <sys/types.h> #include <math.h> #include <private/pixelflinger/ggl_context.h> #include <GLES/gl.h> #define DEBUG_USE_FLOATS 0 // ---------------------------------------------------------------------------- extern "C" GLfixed gglFloatToFixed(float f) __attribute__((const)); // ---------------------------------------------------------------------------- namespace android { namespace gl { GLfloat fixedToFloat(GLfixed) CONST; void sincosf(GLfloat angle, GLfloat* s, GLfloat* c); float sinef(GLfloat x) CONST; float cosinef(GLfloat x) CONST; inline bool cmpf(GLfloat a, GLfloat b) CONST; inline bool isZerof(GLfloat) CONST; inline bool isOnef(GLfloat) CONST; inline int isZeroOrNegativef(GLfloat) CONST; inline int exponent(GLfloat) CONST; inline int32_t mantissa(GLfloat) CONST; inline GLfloat clampToZerof(GLfloat) CONST; inline GLfloat reciprocalf(GLfloat) CONST; inline GLfloat rsqrtf(GLfloat) CONST; inline GLfloat sqrf(GLfloat) CONST; inline GLfloat addExpf(GLfloat v, int e) CONST; inline GLfloat mul2f(GLfloat v) CONST; inline GLfloat div2f(GLfloat v) CONST; inline GLfloat absf(GLfloat v) CONST; /* * float fastexpf(float) : a fast approximation of expf(x) * give somewhat accurate results for -88 <= x <= 88 * * exp(x) = 2^(x/ln(2)) * we use the properties of float encoding * to get a fast 2^ and linear interpolation * */ inline float fastexpf(float y) __attribute__((const)); inline float fastexpf(float y) { union { float r; int32_t i; } u; // 127*ln(2) = 88 if (y < -88.0f) { u.r = 0.0f; } else if (y > 88.0f) { u.r = INFINITY; } else { const float kOneOverLogTwo = (1L<<23) / M_LN2; const int32_t kExponentBias = 127L<<23; const int32_t e = int32_t(y*kOneOverLogTwo); u.i = e + kExponentBias; } return u.r; } bool cmpf(GLfloat a, GLfloat b) { #if DEBUG_USE_FLOATS return a == b; #else union { float f; uint32_t i; } ua, ub; ua.f = a; ub.f = b; return ua.i == ub.i; #endif } bool isZerof(GLfloat v) { #if DEBUG_USE_FLOATS return v == 0; #else union { float f; int32_t i; }; f = v; return (i<<1) == 0; #endif } bool isOnef(GLfloat v) { return cmpf(v, 1.0f); } int isZeroOrNegativef(GLfloat v) { #if DEBUG_USE_FLOATS return v <= 0; #else union { float f; int32_t i; }; f = v; return isZerof(v) | (i>>31); #endif } int exponent(GLfloat v) { union { float f; uint32_t i; }; f = v; return ((i << 1) >> 24) - 127; } int32_t mantissa(GLfloat v) { union { float f; uint32_t i; }; f = v; if (!(i&0x7F800000)) return 0; const int s = i >> 31; i |= (1L<<23); i &= ~0xFF000000; return s ? -i : i; } GLfloat clampToZerof(GLfloat v) { #if DEBUG_USE_FLOATS return v<0 ? 0 : (v>1 ? 1 : v); #else union { float f; int32_t i; }; f = v; i &= ~(i>>31); return f; #endif } GLfloat reciprocalf(GLfloat v) { // XXX: do better return 1.0f / v; } GLfloat rsqrtf(GLfloat v) { // XXX: do better return 1.0f / sqrtf(v); } GLfloat sqrf(GLfloat v) { // XXX: do better return v*v; } GLfloat addExpf(GLfloat v, int e) { union { float f; int32_t i; }; f = v; if (i<<1) { // XXX: deal with over/underflow i += int32_t(e)<<23; } return f; } GLfloat mul2f(GLfloat v) { #if DEBUG_USE_FLOATS return v*2; #else return addExpf(v, 1); #endif } GLfloat div2f(GLfloat v) { #if DEBUG_USE_FLOATS return v*0.5f; #else return addExpf(v, -1); #endif } GLfloat absf(GLfloat v) { #if DEBUG_USE_FLOATS return v<0 ? -v : v; #else union { float f; int32_t i; }; f = v; i &= ~0x80000000; return f; #endif } }; // namespace gl // ---------------------------------------------------------------------------- }; // namespace android #endif // ANDROID_OPENGLES_FP_H