Home | History | Annotate | Download | only in libagl
      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