blob: 6d0c18339f6597e88a678fabb1beb6102c21d6d8 [file] [log] [blame]
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001/* 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