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 34 extern "C" GLfixed gglFloatToFixed(float f) __attribute__((const)); 35 36 // ---------------------------------------------------------------------------- 37 namespace android { 38 39 namespace 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 47 inline bool cmpf(GLfloat a, GLfloat b) CONST; 48 inline bool isZerof(GLfloat) CONST; 49 inline bool isOnef(GLfloat) CONST; 50 51 inline int isZeroOrNegativef(GLfloat) CONST; 52 53 inline int exponent(GLfloat) CONST; 54 inline int32_t mantissa(GLfloat) CONST; 55 inline GLfloat clampToZerof(GLfloat) CONST; 56 inline GLfloat reciprocalf(GLfloat) CONST; 57 inline GLfloat rsqrtf(GLfloat) CONST; 58 inline GLfloat sqrf(GLfloat) CONST; 59 inline GLfloat addExpf(GLfloat v, int e) CONST; 60 inline GLfloat mul2f(GLfloat v) CONST; 61 inline GLfloat div2f(GLfloat v) CONST; 62 inline 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 75 inline float fastexpf(float y) __attribute__((const)); 76 77 inline 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 100 bool 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 114 bool 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 127 bool isOnef(GLfloat v) { 128 return cmpf(v, 1.0f); 129 } 130 131 int 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 144 int exponent(GLfloat v) { 145 union { 146 float f; 147 uint32_t i; 148 }; 149 f = v; 150 return ((i << 1) >> 24) - 127; 151 } 152 153 int32_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 166 GLfloat 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 180 GLfloat reciprocalf(GLfloat v) { 181 // XXX: do better 182 return 1.0f / v; 183 } 184 185 GLfloat rsqrtf(GLfloat v) { 186 // XXX: do better 187 return 1.0f / sqrtf(v); 188 } 189 190 GLfloat sqrf(GLfloat v) { 191 // XXX: do better 192 return v*v; 193 } 194 195 GLfloat 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 207 GLfloat mul2f(GLfloat v) { 208 #if DEBUG_USE_FLOATS 209 return v*2; 210 #else 211 return addExpf(v, 1); 212 #endif 213 } 214 215 GLfloat div2f(GLfloat v) { 216 #if DEBUG_USE_FLOATS 217 return v*0.5f; 218 #else 219 return addExpf(v, -1); 220 #endif 221 } 222 223 GLfloat 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