• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  ** Copyright 2007, The Android Open Source Project
3  **
4  ** Licensed under the Apache License, Version 2.0 (the "License");
5  ** you may not use this file except in compliance with the License.
6  ** You may obtain a copy of the License at
7  **
8  **     http://www.apache.org/licenses/LICENSE-2.0
9  **
10  ** Unless required by applicable law or agreed to in writing, software
11  ** distributed under the License is distributed on an "AS IS" BASIS,
12  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  ** See the License for the specific language governing permissions and
14  ** limitations under the License.
15  */
16 
17 #include <ctype.h>
18 #include <string.h>
19 #include <errno.h>
20 
21 #include <sys/ioctl.h>
22 
23 #include <GLES/gl.h>
24 #include <GLES/glext.h>
25 
26 #include <cutils/log.h>
27 #include <cutils/properties.h>
28 
29 #include "../hooks.h"
30 #include "../egl_impl.h"
31 
32 using namespace android;
33 
34 // ----------------------------------------------------------------------------
35 // extensions for the framework
36 // ----------------------------------------------------------------------------
37 
38 extern "C" {
39 GL_API void GL_APIENTRY glColorPointerBounds(GLint size, GLenum type, GLsizei stride,
40         const GLvoid *ptr, GLsizei count);
41 GL_API void GL_APIENTRY glNormalPointerBounds(GLenum type, GLsizei stride,
42         const GLvoid *pointer, GLsizei count);
43 GL_API void GL_APIENTRY glTexCoordPointerBounds(GLint size, GLenum type,
44         GLsizei stride, const GLvoid *pointer, GLsizei count);
45 GL_API void GL_APIENTRY glVertexPointerBounds(GLint size, GLenum type,
46         GLsizei stride, const GLvoid *pointer, GLsizei count);
47 GL_API void GL_APIENTRY glPointSizePointerOESBounds(GLenum type,
48         GLsizei stride, const GLvoid *pointer, GLsizei count);
49 GL_API void GL_APIENTRY glMatrixIndexPointerOESBounds(GLint size, GLenum type,
50         GLsizei stride, const GLvoid *pointer, GLsizei count);
51 GL_API void GL_APIENTRY glWeightPointerOESBounds(GLint size, GLenum type,
52         GLsizei stride, const GLvoid *pointer, GLsizei count);
53 }
54 
glColorPointerBounds(GLint size,GLenum type,GLsizei stride,const GLvoid * ptr,GLsizei)55 void glColorPointerBounds(GLint size, GLenum type, GLsizei stride,
56         const GLvoid *ptr, GLsizei /*count*/) {
57     glColorPointer(size, type, stride, ptr);
58 }
glNormalPointerBounds(GLenum type,GLsizei stride,const GLvoid * pointer,GLsizei)59 void glNormalPointerBounds(GLenum type, GLsizei stride,
60         const GLvoid *pointer, GLsizei /*count*/) {
61     glNormalPointer(type, stride, pointer);
62 }
glTexCoordPointerBounds(GLint size,GLenum type,GLsizei stride,const GLvoid * pointer,GLsizei)63 void glTexCoordPointerBounds(GLint size, GLenum type,
64         GLsizei stride, const GLvoid *pointer, GLsizei /*count*/) {
65     glTexCoordPointer(size, type, stride, pointer);
66 }
glVertexPointerBounds(GLint size,GLenum type,GLsizei stride,const GLvoid * pointer,GLsizei)67 void glVertexPointerBounds(GLint size, GLenum type,
68         GLsizei stride, const GLvoid *pointer, GLsizei /*count*/) {
69     glVertexPointer(size, type, stride, pointer);
70 }
71 
glPointSizePointerOESBounds(GLenum type,GLsizei stride,const GLvoid * pointer,GLsizei)72 void GL_APIENTRY glPointSizePointerOESBounds(GLenum type,
73         GLsizei stride, const GLvoid *pointer, GLsizei /*count*/) {
74     glPointSizePointerOES(type, stride, pointer);
75 }
76 
glMatrixIndexPointerOESBounds(GLint size,GLenum type,GLsizei stride,const GLvoid * pointer,GLsizei)77 GL_API void GL_APIENTRY glMatrixIndexPointerOESBounds(GLint size, GLenum type,
78         GLsizei stride, const GLvoid *pointer, GLsizei /*count*/) {
79     glMatrixIndexPointerOES(size, type, stride, pointer);
80 }
81 
glWeightPointerOESBounds(GLint size,GLenum type,GLsizei stride,const GLvoid * pointer,GLsizei)82 GL_API void GL_APIENTRY glWeightPointerOESBounds(GLint size, GLenum type,
83         GLsizei stride, const GLvoid *pointer, GLsizei /*count*/) {
84     glWeightPointerOES(size, type, stride, pointer);
85 }
86 
87 // ----------------------------------------------------------------------------
88 // Actual GL entry-points
89 // ----------------------------------------------------------------------------
90 
91 #undef API_ENTRY
92 #undef CALL_GL_API
93 #undef CALL_GL_API_RETURN
94 
95 #if USE_SLOW_BINDING
96 
97     #define API_ENTRY(_api) _api
98 
99     #define CALL_GL_API(_api, ...)                                       \
100         gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;  \
101         if (_c) return _c->_api(__VA_ARGS__);
102 
103 #elif defined(__arm__)
104 
105     #define GET_TLS(reg) "mrc p15, 0, " #reg ", c13, c0, 3 \n"
106 
107     #define API_ENTRY(_api) __attribute__((noinline)) _api
108 
109     #define CALL_GL_API(_api, ...)                              \
110          asm volatile(                                          \
111             GET_TLS(r12)                                        \
112             "ldr   r12, [r12, %[tls]] \n"                       \
113             "cmp   r12, #0            \n"                       \
114             "ldrne pc,  [r12, %[api]] \n"                       \
115             :                                                   \
116             : [tls] "J"(TLS_SLOT_OPENGL_API*4),                 \
117               [api] "J"(__builtin_offsetof(gl_hooks_t, gl._api))    \
118             : "r12"                                             \
119             );
120 
121 #elif defined(__aarch64__)
122 
123     #define API_ENTRY(_api) __attribute__((noinline)) _api
124 
125     #define CALL_GL_API(_api, ...)                                  \
126         asm volatile(                                               \
127             "mrs x16, tpidr_el0\n"                                  \
128             "ldr x16, [x16, %[tls]]\n"                              \
129             "cbz x16, 1f\n"                                         \
130             "ldr x16, [x16, %[api]]\n"                              \
131             "br  x16\n"                                             \
132             "1:\n"                                                  \
133             :                                                       \
134             : [tls] "i" (TLS_SLOT_OPENGL_API * sizeof(void*)),      \
135               [api] "i" (__builtin_offsetof(gl_hooks_t, gl._api))   \
136             : "x16"                                                 \
137         );
138 
139 #elif defined(__i386__)
140 
141     #define API_ENTRY(_api) __attribute__((noinline)) _api
142 
143     #define CALL_GL_API(_api, ...)                                  \
144         register void* fn;                                          \
145         __asm__ volatile(                                           \
146             "mov %%gs:0, %[fn]\n"                                   \
147             "mov %P[tls](%[fn]), %[fn]\n"                           \
148             "test %[fn], %[fn]\n"                                   \
149             "je 1f\n"                                               \
150             "jmp *%P[api](%[fn])\n"                                 \
151             "1:\n"                                                  \
152             : [fn] "=r" (fn)                                        \
153             : [tls] "i" (TLS_SLOT_OPENGL_API*sizeof(void*)),        \
154               [api] "i" (__builtin_offsetof(gl_hooks_t, gl._api))   \
155             : "cc"                                                  \
156             );
157 
158 #elif defined(__x86_64__)
159 
160     #define API_ENTRY(_api) __attribute__((noinline)) _api
161 
162     #define CALL_GL_API(_api, ...)                                  \
163          register void** fn;                                        \
164          __asm__ volatile(                                          \
165             "mov %%fs:0, %[fn]\n"                                   \
166             "mov %P[tls](%[fn]), %[fn]\n"                           \
167             "test %[fn], %[fn]\n"                                   \
168             "je 1f\n"                                               \
169             "jmp *%P[api](%[fn])\n"                                 \
170             "1:\n"                                                  \
171             : [fn] "=r" (fn)                                        \
172             : [tls] "i" (TLS_SLOT_OPENGL_API*sizeof(void*)),        \
173               [api] "i" (__builtin_offsetof(gl_hooks_t, gl._api))   \
174             : "cc"                                                  \
175             );
176 
177 #elif defined(__mips__)
178 
179     #define API_ENTRY(_api) __attribute__((noinline)) _api
180 
181     #define CALL_GL_API(_api, ...)                               \
182         register unsigned int _t0 asm("t0");                     \
183         register unsigned int _fn asm("t1");                     \
184         register unsigned int _tls asm("v1");                    \
185         register unsigned int _v0 asm("v0");                     \
186         asm volatile(                                            \
187             ".set  push\n\t"                                     \
188             ".set  noreorder\n\t"                                \
189             ".set  mips32r2\n\t"                                 \
190             "rdhwr %[tls], $29\n\t"                              \
191             "lw    %[t0], %[OPENGL_API](%[tls])\n\t"             \
192             "beqz  %[t0], 1f\n\t"                                \
193             " move %[fn], $ra\n\t"                               \
194             "lw    %[fn], %[API](%[t0])\n\t"                     \
195             "movz  %[fn], $ra, %[fn]\n\t"                        \
196             "1:\n\t"                                             \
197             "j     %[fn]\n\t"                                    \
198             " move %[v0], $0\n\t"                                \
199             ".set  pop\n\t"                                      \
200             : [fn] "=c"(_fn),                                    \
201               [tls] "=&r"(_tls),                                 \
202               [t0] "=&r"(_t0),                                   \
203               [v0] "=&r"(_v0)                                    \
204             : [OPENGL_API] "I"(TLS_SLOT_OPENGL_API*4),           \
205               [API] "I"(__builtin_offsetof(gl_hooks_t, gl._api)) \
206             :                                                    \
207             );
208 
209 #endif
210 
211 #define CALL_GL_API_RETURN(_api, ...) \
212     CALL_GL_API(_api, __VA_ARGS__) \
213     return 0;
214 
215 
216 extern "C" {
217 #pragma GCC diagnostic ignored "-Wunused-parameter"
218 #include "gl_api.in"
219 #include "glext_api.in"
220 #pragma GCC diagnostic warning "-Wunused-parameter"
221 }
222 
223 #undef API_ENTRY
224 #undef CALL_GL_API
225 #undef CALL_GL_API_RETURN
226 
227 /*
228  * glGetString() is special because we expose some extensions in the wrapper
229  */
230 
231 extern "C" const GLubyte * __glGetString(GLenum name);
232 
glGetString(GLenum name)233 const GLubyte * glGetString(GLenum name) {
234     const GLubyte * ret = egl_get_string_for_current_context(name);
235     if (ret == NULL) {
236         gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;
237         ret = _c->glGetString(name);
238     }
239     return ret;
240 }
241