1/* libs/opengles/fp.h 2** 3** Copyright 2006, The Android Open Source Project 4** 5** Licensed under the Apache License, Version 2.0 (the "License"); 6** you may not use this file except in compliance with the License. 7** You may obtain a copy of the License at 8** 9** http://www.apache.org/licenses/LICENSE-2.0 10** 11** Unless required by applicable law or agreed to in writing, software 12** distributed under the License is distributed on an "AS IS" BASIS, 13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14** See the License for the specific language governing permissions and 15** limitations under the License. 16*/ 17 18#ifndef ANDROID_OPENGLES_FP_H 19#define ANDROID_OPENGLES_FP_H 20 21#include <stdint.h> 22#include <stddef.h> 23#include <sys/types.h> 24#include <math.h> 25 26#include <private/pixelflinger/ggl_context.h> 27 28#include <GLES/gl.h> 29 30#define DEBUG_USE_FLOATS 0 31 32// ---------------------------------------------------------------------------- 33 34extern "C" GLfixed gglFloatToFixed(float f) __attribute__((const)); 35 36// ---------------------------------------------------------------------------- 37namespace android { 38 39namespace gl { 40 41 GLfloat fixedToFloat(GLfixed) CONST; 42 43 void sincosf(GLfloat angle, GLfloat* s, GLfloat* c); 44 float sinef(GLfloat x) CONST; 45 float cosinef(GLfloat x) CONST; 46 47inline bool cmpf(GLfloat a, GLfloat b) CONST; 48inline bool isZerof(GLfloat) CONST; 49inline bool isOnef(GLfloat) CONST; 50 51inline int isZeroOrNegativef(GLfloat) CONST; 52 53inline int exponent(GLfloat) CONST; 54inline int32_t mantissa(GLfloat) CONST; 55inline GLfloat clampToZerof(GLfloat) CONST; 56inline GLfloat reciprocalf(GLfloat) CONST; 57inline GLfloat rsqrtf(GLfloat) CONST; 58inline GLfloat sqrf(GLfloat) CONST; 59inline GLfloat addExpf(GLfloat v, int e) CONST; 60inline GLfloat mul2f(GLfloat v) CONST; 61inline GLfloat div2f(GLfloat v) CONST; 62inline GLfloat absf(GLfloat v) CONST; 63 64 65/* 66 * float fastexpf(float) : a fast approximation of expf(x) 67 * give somewhat accurate results for -88 <= x <= 88 68 * 69 * exp(x) = 2^(x/ln(2)) 70 * we use the properties of float encoding 71 * to get a fast 2^ and linear interpolation 72 * 73 */ 74 75inline float fastexpf(float y) __attribute__((const)); 76 77inline float fastexpf(float y) 78{ 79 union { 80 float r; 81 int32_t i; 82 } u; 83 84 // 127*ln(2) = 88 85 if (y < -88.0f) { 86 u.r = 0.0f; 87 } else if (y > 88.0f) { 88 u.r = INFINITY; 89 } else { 90 const float kOneOverLogTwo = (1L<<23) / M_LN2; 91 const int32_t kExponentBias = 127L<<23; 92 const int32_t e = int32_t(y*kOneOverLogTwo); 93 u.i = e + kExponentBias; 94 } 95 96 return u.r; 97} 98 99 100bool cmpf(GLfloat a, GLfloat b) { 101#if DEBUG_USE_FLOATS 102 return a == b; 103#else 104 union { 105 float f; 106 uint32_t i; 107 } ua, ub; 108 ua.f = a; 109 ub.f = b; 110 return ua.i == ub.i; 111#endif 112} 113 114bool isZerof(GLfloat v) { 115#if DEBUG_USE_FLOATS 116 return v == 0; 117#else 118 union { 119 float f; 120 int32_t i; 121 }; 122 f = v; 123 return (i<<1) == 0; 124#endif 125} 126 127bool isOnef(GLfloat v) { 128 return cmpf(v, 1.0f); 129} 130 131int isZeroOrNegativef(GLfloat v) { 132#if DEBUG_USE_FLOATS 133 return v <= 0; 134#else 135 union { 136 float f; 137 int32_t i; 138 }; 139 f = v; 140 return isZerof(v) | (i>>31); 141#endif 142} 143 144int exponent(GLfloat v) { 145 union { 146 float f; 147 uint32_t i; 148 }; 149 f = v; 150 return ((i << 1) >> 24) - 127; 151} 152 153int32_t mantissa(GLfloat v) { 154 union { 155 float f; 156 uint32_t i; 157 }; 158 f = v; 159 if (!(i&0x7F800000)) return 0; 160 const int s = i >> 31; 161 i |= (1L<<23); 162 i &= ~0xFF000000; 163 return s ? -i : i; 164} 165 166GLfloat clampToZerof(GLfloat v) { 167#if DEBUG_USE_FLOATS 168 return v<0 ? 0 : (v>1 ? 1 : v); 169#else 170 union { 171 float f; 172 int32_t i; 173 }; 174 f = v; 175 i &= ~(i>>31); 176 return f; 177#endif 178} 179 180GLfloat reciprocalf(GLfloat v) { 181 // XXX: do better 182 return 1.0f / v; 183} 184 185GLfloat rsqrtf(GLfloat v) { 186 // XXX: do better 187 return 1.0f / sqrtf(v); 188} 189 190GLfloat sqrf(GLfloat v) { 191 // XXX: do better 192 return v*v; 193} 194 195GLfloat addExpf(GLfloat v, int e) { 196 union { 197 float f; 198 int32_t i; 199 }; 200 f = v; 201 if (i<<1) { // XXX: deal with over/underflow 202 i += int32_t(e)<<23; 203 } 204 return f; 205} 206 207GLfloat mul2f(GLfloat v) { 208#if DEBUG_USE_FLOATS 209 return v*2; 210#else 211 return addExpf(v, 1); 212#endif 213} 214 215GLfloat div2f(GLfloat v) { 216#if DEBUG_USE_FLOATS 217 return v*0.5f; 218#else 219 return addExpf(v, -1); 220#endif 221} 222 223GLfloat absf(GLfloat v) { 224#if DEBUG_USE_FLOATS 225 return v<0 ? -v : v; 226#else 227 union { 228 float f; 229 int32_t i; 230 }; 231 f = v; 232 i &= ~0x80000000; 233 return f; 234#endif 235} 236 237}; // namespace gl 238 239// ---------------------------------------------------------------------------- 240}; // namespace android 241 242#endif // ANDROID_OPENGLES_FP_H 243 244