xref: /aosp_15_r20/frameworks/native/opengl/libs/GLES_CM/gl.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
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 <errno.h>
19 #include <string.h>
20 #include <sys/ioctl.h>
21 
22 #include <log/log.h>
23 #include <cutils/properties.h>
24 
25 #include <GLES/gl.h>
26 #include <GLES/glext.h>
27 
28 #include "../hooks.h"
29 #include "../egl_impl.h"
30 
31 using namespace android;
32 
33 // ----------------------------------------------------------------------------
34 // extensions for the framework
35 // ----------------------------------------------------------------------------
36 
37 extern "C" {
38 GL_API void GL_APIENTRY glColorPointerBounds(GLint size, GLenum type, GLsizei stride,
39         const GLvoid *ptr, GLsizei count);
40 GL_API void GL_APIENTRY glNormalPointerBounds(GLenum type, GLsizei stride,
41         const GLvoid *pointer, GLsizei count);
42 GL_API void GL_APIENTRY glTexCoordPointerBounds(GLint size, GLenum type,
43         GLsizei stride, const GLvoid *pointer, GLsizei count);
44 GL_API void GL_APIENTRY glVertexPointerBounds(GLint size, GLenum type,
45         GLsizei stride, const GLvoid *pointer, GLsizei count);
46 GL_API void GL_APIENTRY glPointSizePointerOESBounds(GLenum type,
47         GLsizei stride, const GLvoid *pointer, GLsizei count);
48 GL_API void GL_APIENTRY glMatrixIndexPointerOESBounds(GLint size, GLenum type,
49         GLsizei stride, const GLvoid *pointer, GLsizei count);
50 GL_API void GL_APIENTRY glWeightPointerOESBounds(GLint size, GLenum type,
51         GLsizei stride, const GLvoid *pointer, GLsizei count);
52 }
53 
glColorPointerBounds(GLint size,GLenum type,GLsizei stride,const GLvoid * ptr,GLsizei)54 void glColorPointerBounds(GLint size, GLenum type, GLsizei stride,
55         const GLvoid *ptr, GLsizei /*count*/) {
56     glColorPointer(size, type, stride, ptr);
57 }
glNormalPointerBounds(GLenum type,GLsizei stride,const GLvoid * pointer,GLsizei)58 void glNormalPointerBounds(GLenum type, GLsizei stride,
59         const GLvoid *pointer, GLsizei /*count*/) {
60     glNormalPointer(type, stride, pointer);
61 }
glTexCoordPointerBounds(GLint size,GLenum type,GLsizei stride,const GLvoid * pointer,GLsizei)62 void glTexCoordPointerBounds(GLint size, GLenum type,
63         GLsizei stride, const GLvoid *pointer, GLsizei /*count*/) {
64     glTexCoordPointer(size, type, stride, pointer);
65 }
glVertexPointerBounds(GLint size,GLenum type,GLsizei stride,const GLvoid * pointer,GLsizei)66 void glVertexPointerBounds(GLint size, GLenum type,
67         GLsizei stride, const GLvoid *pointer, GLsizei /*count*/) {
68     glVertexPointer(size, type, stride, pointer);
69 }
70 
glPointSizePointerOESBounds(GLenum type,GLsizei stride,const GLvoid * pointer,GLsizei)71 void GL_APIENTRY glPointSizePointerOESBounds(GLenum type,
72         GLsizei stride, const GLvoid *pointer, GLsizei /*count*/) {
73     glPointSizePointerOES(type, stride, pointer);
74 }
75 
glMatrixIndexPointerOESBounds(GLint size,GLenum type,GLsizei stride,const GLvoid * pointer,GLsizei)76 GL_API void GL_APIENTRY glMatrixIndexPointerOESBounds(GLint size, GLenum type,
77         GLsizei stride, const GLvoid *pointer, GLsizei /*count*/) {
78     glMatrixIndexPointerOES(size, type, stride, pointer);
79 }
80 
glWeightPointerOESBounds(GLint size,GLenum type,GLsizei stride,const GLvoid * pointer,GLsizei)81 GL_API void GL_APIENTRY glWeightPointerOESBounds(GLint size, GLenum type,
82         GLsizei stride, const GLvoid *pointer, GLsizei /*count*/) {
83     glWeightPointerOES(size, type, stride, pointer);
84 }
85 
86 // ----------------------------------------------------------------------------
87 // Actual GL entry-points
88 // ----------------------------------------------------------------------------
89 
90 #undef API_ENTRY
91 #undef CALL_GL_API
92 #undef CALL_GL_API_INTERNAL_CALL
93 #undef CALL_GL_API_INTERNAL_SET_RETURN_VALUE
94 #undef CALL_GL_API_INTERNAL_DO_RETURN
95 #undef CALL_GL_API_RETURN
96 
97 #if USE_SLOW_BINDING
98 
99     #define API_ENTRY(_api) _api
100 
101     #define CALL_GL_API_INTERNAL_CALL(_api, ...)                         \
102         gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;  \
103         if (_c) return _c->_api(__VA_ARGS__);
104 
105     #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE return 0;
106 
107     // This stays blank, since void functions will implicitly return, and
108     // all of the other functions will return 0 based on the previous macro.
109     #define CALL_GL_API_INTERNAL_DO_RETURN
110 
111 #elif defined(__arm__)
112 
113     #define GET_TLS(reg) "mrc p15, 0, " #reg ", c13, c0, 3 \n"
114 
115     #define API_ENTRY(_api) __attribute__((naked,noinline)) _api
116 
117     #define CALL_GL_API_INTERNAL_CALL(_api, ...)                 \
118         asm volatile(                                            \
119             GET_TLS(r12)                                         \
120             "ldr   r12, [r12, %[tls]] \n"                        \
121             "cmp   r12, #0            \n"                        \
122             "ldrne pc,  [r12, %[api]] \n"                        \
123             :                                                    \
124             : [tls] "J"(TLS_SLOT_OPENGL_API*4),                  \
125               [api] "J"(__builtin_offsetof(gl_hooks_t, gl._api)) \
126             : "r0", "r1", "r2", "r3", "r12"                      \
127         );
128 
129     #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE \
130         asm volatile(                             \
131             "mov r0, #0 \n"                       \
132             :                                     \
133             :                                     \
134             : "r0"                                \
135         );
136 
137 
138     #define CALL_GL_API_INTERNAL_DO_RETURN \
139         asm volatile(                      \
140             "bx lr \n"                     \
141             :                              \
142             :                              \
143             : "r0"                         \
144         );
145 
146 #elif defined(__aarch64__)
147 
148     #define API_ENTRY(_api) __attribute__((naked,noinline)) _api
149 
150     #define CALL_GL_API_INTERNAL_CALL(_api, ...)                    \
151         asm volatile(                                               \
152             "mrs x16, tpidr_el0\n"                                  \
153             "ldr x16, [x16, %[tls]]\n"                              \
154             "cbz x16, 1f\n"                                         \
155             "ldr x16, [x16, %[api]]\n"                              \
156             "br  x16\n"                                             \
157             "1:\n"                                                  \
158             :                                                       \
159             : [tls] "i" (TLS_SLOT_OPENGL_API * sizeof(void*)),      \
160               [api] "i" (__builtin_offsetof(gl_hooks_t, gl._api))   \
161             : "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x16" \
162         );
163 
164     #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE \
165         asm volatile(                             \
166             "mov w0, wzr \n"                      \
167             :                                     \
168             :                                     \
169             : "w0"                                \
170         );
171 
172     #define CALL_GL_API_INTERNAL_DO_RETURN \
173         asm volatile(                      \
174             "ret \n"                       \
175             :                              \
176             :                              \
177             :                              \
178         );
179 
180 #elif defined(__i386__)
181 
182     #define API_ENTRY(_api) __attribute__((naked,noinline)) _api
183 
184     #define CALL_GL_API_INTERNAL_CALL(_api, ...)                    \
185         __asm__ volatile(                                           \
186             "mov %%gs:0, %%eax\n"                                   \
187             "mov %P[tls](%%eax), %%eax\n"                           \
188             "test %%eax, %%eax\n"                                   \
189             "je 1f\n"                                               \
190             "jmp *%P[api](%%eax)\n"                                 \
191             "1:\n"                                                  \
192             :                                                       \
193             : [tls] "i" (TLS_SLOT_OPENGL_API*sizeof(void*)),        \
194               [api] "i" (__builtin_offsetof(gl_hooks_t, gl._api))   \
195             : "cc", "%eax"                                          \
196         );
197 
198     #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE \
199         __asm__ volatile(                         \
200             "xor %%eax, %%eax\n"                  \
201             :                                     \
202             :                                     \
203             : "%eax"                              \
204         );
205 
206     #define CALL_GL_API_INTERNAL_DO_RETURN \
207         __asm__ volatile(                  \
208             "ret\n"                        \
209             :                              \
210             :                              \
211             :                              \
212         );
213 
214 #elif defined(__x86_64__)
215 
216     #define API_ENTRY(_api) __attribute__((naked,noinline)) _api
217 
218     #define CALL_GL_API_INTERNAL_CALL(_api, ...)                    \
219         __asm__ volatile(                                           \
220             "mov %%fs:0, %%rax\n"                                   \
221             "mov %P[tls](%%rax), %%rax\n"                           \
222             "test %%rax, %%rax\n"                                   \
223             "je 1f\n"                                               \
224             "jmp *%P[api](%%rax)\n"                                 \
225             "1:\n"                                                  \
226             :                                                       \
227             : [tls] "i" (TLS_SLOT_OPENGL_API*sizeof(void*)),        \
228               [api] "i" (__builtin_offsetof(gl_hooks_t, gl._api))   \
229             : "cc", "%rdi", "%rsi", "%rdx", "%rcx", "%r8", "%r9",   \
230               "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", \
231               "%xmm6", "%xmm7"                                      \
232         );
233 
234     #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE \
235         __asm__ volatile(                         \
236             "xor %%eax, %%eax\n"                  \
237             :                                     \
238             :                                     \
239             : "%eax"                              \
240         );
241 
242     #define CALL_GL_API_INTERNAL_DO_RETURN \
243         __asm__ volatile(                  \
244             "retq\n"                       \
245             :                              \
246             :                              \
247             :                              \
248         );
249 
250 #elif defined(__riscv)
251 
252     #define API_ENTRY(_api) __attribute__((naked,noinline)) _api
253 
254     #define CALL_GL_API_INTERNAL_CALL(_api, ...)                 \
255         asm volatile(                                            \
256             "mv t0, tp\n"                                        \
257             "li t1, %[tls]\n"                                    \
258             "add t0, t0, t1\n"                                   \
259             "ld t0, 0(t0)\n"                                     \
260             "beqz t0, 1f\n"                                      \
261             "li t1, %[api]\n"                                    \
262             "add t0, t0, t1\n"                                   \
263             "ld t0, 0(t0)\n"                                     \
264             "jalr x0, t0\n"                                      \
265             "1:\n"                                               \
266             :                                                    \
267             : [tls] "i"(TLS_SLOT_OPENGL_API*sizeof(void *)),     \
268               [api] "i"(__builtin_offsetof(gl_hooks_t, gl._api)) \
269             : "t0", "t1", "t2", "a0", "a1", "a2", "a3", "a4",    \
270               "a5", "t6", "t3", "t4", "t5", "t6"                 \
271         );
272 
273     #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE \
274         asm volatile(                             \
275             "li a0, 0\n"                          \
276             :                                     \
277             :                                     \
278             : "a0"                                \
279         );
280 
281     #define CALL_GL_API_INTERNAL_DO_RETURN \
282         asm volatile(                      \
283             "ret\n"                        \
284             :                              \
285             :                              \
286             :                              \
287         );
288 
289 #endif
290 
291 #define CALL_GL_API(_api, ...) \
292     CALL_GL_API_INTERNAL_CALL(_api, __VA_ARGS__) \
293     CALL_GL_API_INTERNAL_DO_RETURN
294 
295 #define CALL_GL_API_RETURN(_api, ...) \
296     CALL_GL_API_INTERNAL_CALL(_api, __VA_ARGS__) \
297     CALL_GL_API_INTERNAL_SET_RETURN_VALUE \
298     CALL_GL_API_INTERNAL_DO_RETURN
299 
300 extern "C" {
301 #pragma GCC diagnostic ignored "-Wunused-parameter"
302 #include "gl_api.in"
303 #include "glext_api.in"
304 #pragma GCC diagnostic warning "-Wunused-parameter"
305 }
306 
307 #undef API_ENTRY
308 #undef CALL_GL_API
309 #undef CALL_GL_API_INTERNAL_CALL
310 #undef CALL_GL_API_INTERNAL_SET_RETURN_VALUE
311 #undef CALL_GL_API_INTERNAL_DO_RETURN
312 #undef CALL_GL_API_RETURN
313 
314 /*
315  * glGetString() is special because we expose some extensions in the wrapper
316  */
317 
318 extern "C" const GLubyte * __glGetString(GLenum name);
319 
glGetString(GLenum name)320 const GLubyte * glGetString(GLenum name) {
321     const GLubyte * ret = egl_get_string_for_current_context(name);
322     if (ret == NULL) {
323         gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;
324         ret = _c->glGetString(name);
325     }
326     return ret;
327 }
328