1/* libs/opengles/matrix.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_MATRIX_H
19#define ANDROID_OPENGLES_MATRIX_H
20
21#include <stdint.h>
22#include <stddef.h>
23#include <sys/types.h>
24#include <utils/Log.h>
25
26#include <private/pixelflinger/ggl_context.h>
27
28#include <GLES/gl.h>
29
30namespace android {
31
32const int OGLES_MODELVIEW_STACK_DEPTH   = 16;
33const int OGLES_PROJECTION_STACK_DEPTH  =  2;
34const int OGLES_TEXTURE_STACK_DEPTH     =  2;
35
36void ogles_init_matrix(ogles_context_t*);
37void ogles_uninit_matrix(ogles_context_t*);
38void ogles_invalidate_perspective(ogles_context_t* c);
39void ogles_validate_transform_impl(ogles_context_t* c, uint32_t want);
40
41int ogles_surfaceport(ogles_context_t* c, GLint x, GLint y);
42
43void ogles_scissor(ogles_context_t* c,
44        GLint x, GLint y, GLsizei w, GLsizei h);
45
46void ogles_viewport(ogles_context_t* c,
47        GLint x, GLint y, GLsizei w, GLsizei h);
48
49inline void ogles_validate_transform(
50        ogles_context_t* c, uint32_t want)
51{
52    if (c->transforms.dirty & want)
53        ogles_validate_transform_impl(c, want);
54}
55
56// ----------------------------------------------------------------------------
57
58inline
59GLfixed vsquare3(GLfixed a, GLfixed b, GLfixed c)
60{
61#if defined(__arm__) && !defined(__thumb__)
62
63    GLfixed r;
64    int32_t t;
65    asm(
66        "smull %0, %1, %2, %2       \n"
67        "smlal %0, %1, %3, %3       \n"
68        "smlal %0, %1, %4, %4       \n"
69        "movs  %0, %0, lsr #16      \n"
70        "adc   %0, %0, %1, lsl #16  \n"
71        :   "=&r"(r), "=&r"(t)
72        :   "%r"(a), "r"(b), "r"(c)
73        :   "cc"
74        );
75    return r;
76
77#else
78
79    return ((   int64_t(a)*a +
80                int64_t(b)*b +
81                int64_t(c)*c + 0x8000)>>16);
82
83#endif
84}
85
86static inline GLfixed mla2a( GLfixed a0, GLfixed b0,
87                            GLfixed a1, GLfixed b1,
88                            GLfixed c)
89{
90#if defined(__arm__) && !defined(__thumb__)
91
92    GLfixed r;
93    int32_t t;
94    asm(
95        "smull %0, %1, %2, %3       \n"
96        "smlal %0, %1, %4, %5       \n"
97        "add   %0, %6, %0, lsr #16  \n"
98        "add   %0, %0, %1, lsl #16  \n"
99        :   "=&r"(r), "=&r"(t)
100        :   "%r"(a0), "r"(b0),
101            "%r"(a1), "r"(b1),
102            "r"(c)
103        :
104        );
105    return r;
106
107#else
108
109    return ((   int64_t(a0)*b0 +
110                int64_t(a1)*b1)>>16) + c;
111
112#endif
113}
114
115static inline GLfixed mla3a( GLfixed a0, GLfixed b0,
116                             GLfixed a1, GLfixed b1,
117                             GLfixed a2, GLfixed b2,
118                             GLfixed c)
119{
120#if defined(__arm__) && !defined(__thumb__)
121
122    GLfixed r;
123    int32_t t;
124    asm(
125        "smull %0, %1, %2, %3       \n"
126        "smlal %0, %1, %4, %5       \n"
127        "smlal %0, %1, %6, %7       \n"
128        "add   %0, %8, %0, lsr #16  \n"
129        "add   %0, %0, %1, lsl #16  \n"
130        :   "=&r"(r), "=&r"(t)
131        :   "%r"(a0), "r"(b0),
132            "%r"(a1), "r"(b1),
133            "%r"(a2), "r"(b2),
134            "r"(c)
135        :
136        );
137    return r;
138
139#else
140
141    return ((   int64_t(a0)*b0 +
142                int64_t(a1)*b1 +
143                int64_t(a2)*b2)>>16) + c;
144
145#endif
146}
147
148// b0, b1, b2 are signed 16-bit quanities
149// that have been shifted right by 'shift' bits relative to normal
150// S16.16 fixed point
151static inline GLfixed mla3a16( GLfixed a0, int32_t b1b0,
152                               GLfixed a1,
153                               GLfixed a2, int32_t b2,
154                               GLint shift,
155                               GLfixed c)
156{
157#if defined(__arm__) && !defined(__thumb__)
158
159    GLfixed r;
160    asm(
161        "smulwb %0, %1, %2          \n"
162        "smlawt %0, %3, %2, %0      \n"
163        "smlawb %0, %4, %5, %0      \n"
164        "add    %0, %7, %0, lsl %6  \n"
165        :   "=&r"(r)
166        :   "r"(a0), "r"(b1b0),
167            "r"(a1),
168            "r"(a2), "r"(b2),
169            "r"(shift),
170            "r"(c)
171        :
172        );
173    return r;
174
175#else
176
177    int32_t accum;
178    int16_t b0 = b1b0 & 0xffff;
179    int16_t b1 = (b1b0 >> 16) & 0xffff;
180    accum  = int64_t(a0)*int16_t(b0) >> 16;
181    accum += int64_t(a1)*int16_t(b1) >> 16;
182    accum += int64_t(a2)*int16_t(b2) >> 16;
183    accum = (accum << shift) + c;
184    return accum;
185
186#endif
187}
188
189
190static inline GLfixed mla3a16_btb( GLfixed a0,
191                                   GLfixed a1,
192                                   GLfixed a2,
193                                   int32_t b1b0, int32_t xxb2,
194                                   GLint shift,
195                                   GLfixed c)
196{
197#if defined(__arm__) && !defined(__thumb__)
198
199    GLfixed r;
200    asm(
201        "smulwb %0, %1, %4          \n"
202        "smlawt %0, %2, %4, %0      \n"
203        "smlawb %0, %3, %5, %0      \n"
204        "add    %0, %7, %0, lsl %6  \n"
205        :   "=&r"(r)
206        :   "r"(a0),
207            "r"(a1),
208            "r"(a2),
209            "r"(b1b0), "r"(xxb2),
210            "r"(shift),
211            "r"(c)
212        :
213        );
214    return r;
215
216#else
217
218    int32_t accum;
219    int16_t b0 =  b1b0        & 0xffff;
220    int16_t b1 = (b1b0 >> 16) & 0xffff;
221    int16_t b2 =  xxb2        & 0xffff;
222    accum  = int64_t(a0)*int16_t(b0) >> 16;
223    accum += int64_t(a1)*int16_t(b1) >> 16;
224    accum += int64_t(a2)*int16_t(b2) >> 16;
225    accum = (accum << shift) + c;
226    return accum;
227
228#endif
229}
230
231static inline GLfixed mla3a16_btt( GLfixed a0,
232                                   GLfixed a1,
233                                   GLfixed a2,
234                                   int32_t b1b0, int32_t b2xx,
235                                   GLint shift,
236                                   GLfixed c)
237{
238#if defined(__arm__) && !defined(__thumb__)
239
240    GLfixed r;
241    asm(
242        "smulwb %0, %1, %4          \n"
243        "smlawt %0, %2, %4, %0      \n"
244        "smlawt %0, %3, %5, %0      \n"
245        "add    %0, %7, %0, lsl %6  \n"
246        :   "=&r"(r)
247        :   "r"(a0),
248            "r"(a1),
249            "r"(a2),
250            "r"(b1b0), "r"(b2xx),
251            "r"(shift),
252            "r"(c)
253        :
254        );
255    return r;
256
257#else
258
259    int32_t accum;
260    int16_t b0 =  b1b0        & 0xffff;
261    int16_t b1 = (b1b0 >> 16) & 0xffff;
262    int16_t b2 = (b2xx >> 16) & 0xffff;
263    accum  = int64_t(a0)*int16_t(b0) >> 16;
264    accum += int64_t(a1)*int16_t(b1) >> 16;
265    accum += int64_t(a2)*int16_t(b2) >> 16;
266    accum = (accum << shift) + c;
267    return accum;
268
269#endif
270}
271
272static inline GLfixed mla3( GLfixed a0, GLfixed b0,
273                            GLfixed a1, GLfixed b1,
274                            GLfixed a2, GLfixed b2)
275{
276#if defined(__arm__) && !defined(__thumb__)
277
278    GLfixed r;
279    int32_t t;
280    asm(
281        "smull %0, %1, %2, %3       \n"
282        "smlal %0, %1, %4, %5       \n"
283        "smlal %0, %1, %6, %7       \n"
284        "movs  %0, %0, lsr #16      \n"
285        "adc   %0, %0, %1, lsl #16  \n"
286        :   "=&r"(r), "=&r"(t)
287        :   "%r"(a0), "r"(b0),
288            "%r"(a1), "r"(b1),
289            "%r"(a2), "r"(b2)
290        :   "cc"
291        );
292    return r;
293
294#else
295
296    return ((   int64_t(a0)*b0 +
297                int64_t(a1)*b1 +
298                int64_t(a2)*b2 + 0x8000)>>16);
299
300#endif
301}
302
303static inline GLfixed mla4( GLfixed a0, GLfixed b0,
304                            GLfixed a1, GLfixed b1,
305                            GLfixed a2, GLfixed b2,
306                            GLfixed a3, GLfixed b3)
307{
308#if defined(__arm__) && !defined(__thumb__)
309
310    GLfixed r;
311    int32_t t;
312    asm(
313        "smull %0, %1, %2, %3       \n"
314        "smlal %0, %1, %4, %5       \n"
315        "smlal %0, %1, %6, %7       \n"
316        "smlal %0, %1, %8, %9       \n"
317        "movs  %0, %0, lsr #16      \n"
318        "adc   %0, %0, %1, lsl #16  \n"
319        :   "=&r"(r), "=&r"(t)
320        :   "%r"(a0), "r"(b0),
321            "%r"(a1), "r"(b1),
322            "%r"(a2), "r"(b2),
323            "%r"(a3), "r"(b3)
324        :   "cc"
325        );
326    return r;
327
328#else
329
330    return ((   int64_t(a0)*b0 +
331                int64_t(a1)*b1 +
332                int64_t(a2)*b2 +
333                int64_t(a3)*b3 + 0x8000)>>16);
334
335#endif
336}
337
338inline
339GLfixed dot4(const GLfixed* a, const GLfixed* b)
340{
341    return mla4(a[0], b[0], a[1], b[1], a[2], b[2], a[3], b[3]);
342}
343
344
345inline
346GLfixed dot3(const GLfixed* a, const GLfixed* b)
347{
348    return mla3(a[0], b[0], a[1], b[1], a[2], b[2]);
349}
350
351
352}; // namespace android
353
354#endif // ANDROID_OPENGLES_MATRIX_H
355
356