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#elif defined(__mips__) && !defined(__LP64__) && __mips_isa_rev < 6
78
79    GLfixed res;
80    int32_t t1,t2,t3;
81    asm(
82        "mult  %[a], %[a]       \r\n"
83        "li    %[res],0x8000 \r\n"
84        "madd   %[b],%[b] \r\n"
85        "move   %[t3],$zero \r\n"
86        "madd   %[c],%[c] \r\n"
87        "mflo   %[t1]\r\n"
88        "mfhi   %[t2]\r\n"
89        "addu   %[t1],%[res],%[t1]\r\n"          /*add 0x8000*/
90        "sltu   %[t3],%[t1],%[res]\r\n"
91        "addu   %[t2],%[t2],%[t3]\r\n"
92        "srl    %[res],%[t1],16\r\n"
93        "sll    %[t2],%[t2],16\r\n"
94        "or     %[res],%[res],%[t2]\r\n"
95        :   [res]"=&r"(res),[t1]"=&r"(t1),[t2]"=&r"(t2),[t3]"=&r"(t3)
96        :   [a] "r" (a),[b] "r" (b),[c] "r" (c)
97        : "%hi","%lo"
98        );
99    return res;
100
101#else
102
103    return ((   int64_t(a)*a +
104                int64_t(b)*b +
105                int64_t(c)*c + 0x8000)>>16);
106
107#endif
108}
109
110static inline GLfixed mla2a( GLfixed a0, GLfixed b0,
111                            GLfixed a1, GLfixed b1,
112                            GLfixed c)
113{
114#if defined(__arm__) && !defined(__thumb__)
115
116    GLfixed r;
117    int32_t t;
118    asm(
119        "smull %0, %1, %2, %3       \n"
120        "smlal %0, %1, %4, %5       \n"
121        "add   %0, %6, %0, lsr #16  \n"
122        "add   %0, %0, %1, lsl #16  \n"
123        :   "=&r"(r), "=&r"(t)
124        :   "%r"(a0), "r"(b0),
125            "%r"(a1), "r"(b1),
126            "r"(c)
127        :
128        );
129    return r;
130
131#else
132
133    return ((   int64_t(a0)*b0 +
134                int64_t(a1)*b1)>>16) + c;
135
136#endif
137}
138
139static inline GLfixed mla3a( GLfixed a0, GLfixed b0,
140                             GLfixed a1, GLfixed b1,
141                             GLfixed a2, GLfixed b2,
142                             GLfixed c)
143{
144#if defined(__arm__) && !defined(__thumb__)
145
146    GLfixed r;
147    int32_t t;
148    asm(
149        "smull %0, %1, %2, %3       \n"
150        "smlal %0, %1, %4, %5       \n"
151        "smlal %0, %1, %6, %7       \n"
152        "add   %0, %8, %0, lsr #16  \n"
153        "add   %0, %0, %1, lsl #16  \n"
154        :   "=&r"(r), "=&r"(t)
155        :   "%r"(a0), "r"(b0),
156            "%r"(a1), "r"(b1),
157            "%r"(a2), "r"(b2),
158            "r"(c)
159        :
160        );
161    return r;
162
163#elif defined(__mips__)  && !defined(__LP64__) && __mips_isa_rev < 6
164
165    GLfixed res;
166    int32_t t1,t2;
167    asm(
168        "mult  %[a0],%[b0]       \r\n"
169        "madd  %[a1],%[b1]       \r\n"
170        "madd  %[a2],%[b2]       \r\n"
171        "mflo  %[t2]\r\n"
172        "mfhi  %[t1]\r\n"
173        "srl    %[t2],%[t2],16\r\n"
174        "sll    %[t1],%[t1],16\r\n"
175        "or     %[t2],%[t2],%[t1]\r\n"
176        "addu   %[res],%[t2],%[c]"
177        :   [res]"=&r"(res),[t1]"=&r"(t1),[t2]"=&r"(t2)
178        :   [a0] "r" (a0),[b0] "r" (b0),[a1] "r" (a1),[b1] "r" (b1),[a2] "r" (a2),[b2] "r" (b2),[c] "r" (c)
179        : "%hi","%lo"
180        );
181    return res;
182
183#else
184
185    return ((   int64_t(a0)*b0 +
186                int64_t(a1)*b1 +
187                int64_t(a2)*b2)>>16) + c;
188
189#endif
190}
191
192// b0, b1, b2 are signed 16-bit quanities
193// that have been shifted right by 'shift' bits relative to normal
194// S16.16 fixed point
195static inline GLfixed mla3a16( GLfixed a0, int32_t b1b0,
196                               GLfixed a1,
197                               GLfixed a2, int32_t b2,
198                               GLint shift,
199                               GLfixed c)
200{
201#if defined(__arm__) && !defined(__thumb__)
202
203    GLfixed r;
204    asm(
205        "smulwb %0, %1, %2          \n"
206        "smlawt %0, %3, %2, %0      \n"
207        "smlawb %0, %4, %5, %0      \n"
208        "add    %0, %7, %0, lsl %6  \n"
209        :   "=&r"(r)
210        :   "r"(a0), "r"(b1b0),
211            "r"(a1),
212            "r"(a2), "r"(b2),
213            "r"(shift),
214            "r"(c)
215        :
216        );
217    return r;
218
219#else
220
221    int32_t accum;
222    int16_t b0 = b1b0 & 0xffff;
223    int16_t b1 = (b1b0 >> 16) & 0xffff;
224    accum  = int64_t(a0)*int16_t(b0) >> 16;
225    accum += int64_t(a1)*int16_t(b1) >> 16;
226    accum += int64_t(a2)*int16_t(b2) >> 16;
227    accum = (accum << shift) + c;
228    return accum;
229
230#endif
231}
232
233
234static inline GLfixed mla3a16_btb( GLfixed a0,
235                                   GLfixed a1,
236                                   GLfixed a2,
237                                   int32_t b1b0, int32_t xxb2,
238                                   GLint shift,
239                                   GLfixed c)
240{
241#if defined(__arm__) && !defined(__thumb__)
242
243    GLfixed r;
244    asm(
245        "smulwb %0, %1, %4          \n"
246        "smlawt %0, %2, %4, %0      \n"
247        "smlawb %0, %3, %5, %0      \n"
248        "add    %0, %7, %0, lsl %6  \n"
249        :   "=&r"(r)
250        :   "r"(a0),
251            "r"(a1),
252            "r"(a2),
253            "r"(b1b0), "r"(xxb2),
254            "r"(shift),
255            "r"(c)
256        :
257        );
258    return r;
259
260#else
261
262    int32_t accum;
263    int16_t b0 =  b1b0        & 0xffff;
264    int16_t b1 = (b1b0 >> 16) & 0xffff;
265    int16_t b2 =  xxb2        & 0xffff;
266    accum  = int64_t(a0)*int16_t(b0) >> 16;
267    accum += int64_t(a1)*int16_t(b1) >> 16;
268    accum += int64_t(a2)*int16_t(b2) >> 16;
269    accum = (accum << shift) + c;
270    return accum;
271
272#endif
273}
274
275static inline GLfixed mla3a16_btt( GLfixed a0,
276                                   GLfixed a1,
277                                   GLfixed a2,
278                                   int32_t b1b0, int32_t b2xx,
279                                   GLint shift,
280                                   GLfixed c)
281{
282#if defined(__arm__) && !defined(__thumb__)
283
284    GLfixed r;
285    asm(
286        "smulwb %0, %1, %4          \n"
287        "smlawt %0, %2, %4, %0      \n"
288        "smlawt %0, %3, %5, %0      \n"
289        "add    %0, %7, %0, lsl %6  \n"
290        :   "=&r"(r)
291        :   "r"(a0),
292            "r"(a1),
293            "r"(a2),
294            "r"(b1b0), "r"(b2xx),
295            "r"(shift),
296            "r"(c)
297        :
298        );
299    return r;
300
301#else
302
303    int32_t accum;
304    int16_t b0 =  b1b0        & 0xffff;
305    int16_t b1 = (b1b0 >> 16) & 0xffff;
306    int16_t b2 = (b2xx >> 16) & 0xffff;
307    accum  = int64_t(a0)*int16_t(b0) >> 16;
308    accum += int64_t(a1)*int16_t(b1) >> 16;
309    accum += int64_t(a2)*int16_t(b2) >> 16;
310    accum = (accum << shift) + c;
311    return accum;
312
313#endif
314}
315
316static inline GLfixed mla3( GLfixed a0, GLfixed b0,
317                            GLfixed a1, GLfixed b1,
318                            GLfixed a2, GLfixed b2)
319{
320#if defined(__arm__) && !defined(__thumb__)
321
322    GLfixed r;
323    int32_t t;
324    asm(
325        "smull %0, %1, %2, %3       \n"
326        "smlal %0, %1, %4, %5       \n"
327        "smlal %0, %1, %6, %7       \n"
328        "movs  %0, %0, lsr #16      \n"
329        "adc   %0, %0, %1, lsl #16  \n"
330        :   "=&r"(r), "=&r"(t)
331        :   "%r"(a0), "r"(b0),
332            "%r"(a1), "r"(b1),
333            "%r"(a2), "r"(b2)
334        :   "cc"
335        );
336    return r;
337
338#else
339
340    return ((   int64_t(a0)*b0 +
341                int64_t(a1)*b1 +
342                int64_t(a2)*b2 + 0x8000)>>16);
343
344#endif
345}
346
347static inline GLfixed mla4( GLfixed a0, GLfixed b0,
348                            GLfixed a1, GLfixed b1,
349                            GLfixed a2, GLfixed b2,
350                            GLfixed a3, GLfixed b3)
351{
352#if defined(__arm__) && !defined(__thumb__)
353
354    GLfixed r;
355    int32_t t;
356    asm(
357        "smull %0, %1, %2, %3       \n"
358        "smlal %0, %1, %4, %5       \n"
359        "smlal %0, %1, %6, %7       \n"
360        "smlal %0, %1, %8, %9       \n"
361        "movs  %0, %0, lsr #16      \n"
362        "adc   %0, %0, %1, lsl #16  \n"
363        :   "=&r"(r), "=&r"(t)
364        :   "%r"(a0), "r"(b0),
365            "%r"(a1), "r"(b1),
366            "%r"(a2), "r"(b2),
367            "%r"(a3), "r"(b3)
368        :   "cc"
369        );
370    return r;
371
372#else
373
374    return ((   int64_t(a0)*b0 +
375                int64_t(a1)*b1 +
376                int64_t(a2)*b2 +
377                int64_t(a3)*b3 + 0x8000)>>16);
378
379#endif
380}
381
382inline
383GLfixed dot4(const GLfixed* a, const GLfixed* b)
384{
385    return mla4(a[0], b[0], a[1], b[1], a[2], b[2], a[3], b[3]);
386}
387
388
389inline
390GLfixed dot3(const GLfixed* a, const GLfixed* b)
391{
392    return mla3(a[0], b[0], a[1], b[1], a[2], b[2]);
393}
394
395
396}; // namespace android
397
398#endif // ANDROID_OPENGLES_MATRIX_H
399
400