blob: 65f50f54fb7837859fd9014e608ec3aeacd11482 [file] [log] [blame]
Jesse Hall47743382013-02-08 11:13:46 -08001/*
Mathias Agopianb1a39d62009-05-27 20:38:06 -07002 ** Copyright 2007, The Android Open Source Project
3 **
Jesse Hall47743382013-02-08 11:13:46 -08004 ** 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
Mathias Agopianb1a39d62009-05-27 20:38:06 -07007 **
Jesse Hall47743382013-02-08 11:13:46 -08008 ** http://www.apache.org/licenses/LICENSE-2.0
Mathias Agopianb1a39d62009-05-27 20:38:06 -07009 **
Jesse Hall47743382013-02-08 11:13:46 -080010 ** 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
Mathias Agopianb1a39d62009-05-27 20:38:06 -070014 ** limitations under the License.
15 */
16
17#include <ctype.h>
Mathias Agopianb1a39d62009-05-27 20:38:06 -070018#include <errno.h>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070019#include <string.h>
Mathias Agopianb1a39d62009-05-27 20:38:06 -070020#include <sys/ioctl.h>
21
Mathias Agopian5f1af042017-03-09 18:50:05 -080022#include <log/log.h>
Mathias Agopianb1a39d62009-05-27 20:38:06 -070023#include <cutils/properties.h>
24
Mathias Agopian39c24a22013-04-04 23:17:56 -070025#include "../hooks.h"
26#include "../egl_impl.h"
Mathias Agopianb1a39d62009-05-27 20:38:06 -070027
28using namespace android;
29
30// ----------------------------------------------------------------------------
31// Actual GL entry-points
32// ----------------------------------------------------------------------------
33
34#undef API_ENTRY
35#undef CALL_GL_API
Stephen Hines3e8fce42016-03-22 23:35:27 -070036#undef CALL_GL_API_INTERNAL_CALL
37#undef CALL_GL_API_INTERNAL_SET_RETURN_VALUE
38#undef CALL_GL_API_INTERNAL_DO_RETURN
Mathias Agopianb1a39d62009-05-27 20:38:06 -070039#undef CALL_GL_API_RETURN
40
Jesse Hall30a41aa2014-05-30 23:32:12 -070041#if USE_SLOW_BINDING
42
43 #define API_ENTRY(_api) _api
44
Stephen Hines3e8fce42016-03-22 23:35:27 -070045 #define CALL_GL_API_INTERNAL_CALL(_api, ...) \
Jesse Hall30a41aa2014-05-30 23:32:12 -070046 gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \
47 if (_c) return _c->_api(__VA_ARGS__);
48
Stephen Hines3e8fce42016-03-22 23:35:27 -070049 #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE return 0;
50
51 // This stays blank, since void functions will implicitly return, and
52 // all of the other functions will return 0 based on the previous macro.
53 #define CALL_GL_API_INTERNAL_DO_RETURN
54
Jesse Hall30a41aa2014-05-30 23:32:12 -070055#elif defined(__arm__)
Duane Sand46b42532013-03-27 10:58:06 -070056
Elliott Hughes288870e2013-02-13 17:30:54 -080057 #define GET_TLS(reg) "mrc p15, 0, " #reg ", c13, c0, 3 \n"
Mathias Agopian673d2db2009-10-14 02:39:53 -070058
Stephen Hines3e8fce42016-03-22 23:35:27 -070059 #define API_ENTRY(_api) __attribute__((naked,noinline)) _api
Mathias Agopianb1a39d62009-05-27 20:38:06 -070060
Stephen Hines3e8fce42016-03-22 23:35:27 -070061 #define CALL_GL_API_INTERNAL_CALL(_api, ...) \
62 asm volatile( \
63 GET_TLS(r12) \
64 "ldr r12, [r12, %[tls]] \n" \
65 "cmp r12, #0 \n" \
66 "ldrne pc, [r12, %[api]] \n" \
67 : \
68 : [tls] "J"(TLS_SLOT_OPENGL_API*4), \
69 [api] "J"(__builtin_offsetof(gl_hooks_t, gl._api)) \
70 : "r0", "r1", "r2", "r3", "r12" \
71 );
72
73 #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE \
74 asm volatile( \
75 "mov r0, #0 \n" \
76 : \
77 : \
78 : "r0" \
79 );
80
81
82 #define CALL_GL_API_INTERNAL_DO_RETURN \
83 asm volatile( \
84 "bx lr \n" \
85 : \
86 : \
87 : "r0" \
88 );
Mathias Agopian673d2db2009-10-14 02:39:53 -070089
Jesse Hall30a41aa2014-05-30 23:32:12 -070090#elif defined(__aarch64__)
91
Stephen Hines3e8fce42016-03-22 23:35:27 -070092 #define API_ENTRY(_api) __attribute__((naked,noinline)) _api
Jesse Hall30a41aa2014-05-30 23:32:12 -070093
Stephen Hines3e8fce42016-03-22 23:35:27 -070094 #define CALL_GL_API_INTERNAL_CALL(_api, ...) \
Jesse Hall30a41aa2014-05-30 23:32:12 -070095 asm volatile( \
96 "mrs x16, tpidr_el0\n" \
97 "ldr x16, [x16, %[tls]]\n" \
98 "cbz x16, 1f\n" \
99 "ldr x16, [x16, %[api]]\n" \
100 "br x16\n" \
101 "1:\n" \
102 : \
103 : [tls] "i" (TLS_SLOT_OPENGL_API * sizeof(void*)), \
104 [api] "i" (__builtin_offsetof(gl_hooks_t, gl._api)) \
Stephen Hines3e8fce42016-03-22 23:35:27 -0700105 : "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x16" \
106 );
107
108 #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE \
109 asm volatile( \
110 "mov w0, wzr \n" \
111 : \
112 : \
113 : "w0" \
114 );
115
116 #define CALL_GL_API_INTERNAL_DO_RETURN \
117 asm volatile( \
118 "ret \n" \
119 : \
120 : \
121 : \
Jesse Hall30a41aa2014-05-30 23:32:12 -0700122 );
123
124#elif defined(__i386__)
mwajdeczc80aafa2014-05-26 13:56:37 +0200125
Stephen Hines3e8fce42016-03-22 23:35:27 -0700126 #define API_ENTRY(_api) __attribute__((naked,noinline)) _api
mwajdeczc80aafa2014-05-26 13:56:37 +0200127
Stephen Hines3e8fce42016-03-22 23:35:27 -0700128 #define CALL_GL_API_INTERNAL_CALL(_api, ...) \
mwajdeczc80aafa2014-05-26 13:56:37 +0200129 __asm__ volatile( \
Stephen Hines3e8fce42016-03-22 23:35:27 -0700130 "mov %%gs:0, %%eax\n" \
131 "mov %P[tls](%%eax), %%eax\n" \
132 "test %%eax, %%eax\n" \
mwajdeczc80aafa2014-05-26 13:56:37 +0200133 "je 1f\n" \
Stephen Hines3e8fce42016-03-22 23:35:27 -0700134 "jmp *%P[api](%%eax)\n" \
mwajdeczc80aafa2014-05-26 13:56:37 +0200135 "1:\n" \
Stephen Hines3e8fce42016-03-22 23:35:27 -0700136 : \
mwajdeczc80aafa2014-05-26 13:56:37 +0200137 : [tls] "i" (TLS_SLOT_OPENGL_API*sizeof(void*)), \
138 [api] "i" (__builtin_offsetof(gl_hooks_t, gl._api)) \
Stephen Hines3e8fce42016-03-22 23:35:27 -0700139 : "cc", "%eax" \
mwajdeczc80aafa2014-05-26 13:56:37 +0200140 );
141
Stephen Hines3e8fce42016-03-22 23:35:27 -0700142 #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE \
143 __asm__ volatile( \
144 "xor %%eax, %%eax\n" \
145 : \
146 : \
147 : "%eax" \
148 );
149
150 #define CALL_GL_API_INTERNAL_DO_RETURN \
151 __asm__ volatile( \
152 "ret\n" \
153 : \
154 : \
155 : \
156 );
157
Jesse Hall30a41aa2014-05-30 23:32:12 -0700158#elif defined(__x86_64__)
mwajdeczc80aafa2014-05-26 13:56:37 +0200159
Stephen Hines3e8fce42016-03-22 23:35:27 -0700160 #define API_ENTRY(_api) __attribute__((naked,noinline)) _api
mwajdeczc80aafa2014-05-26 13:56:37 +0200161
Stephen Hines3e8fce42016-03-22 23:35:27 -0700162 #define CALL_GL_API_INTERNAL_CALL(_api, ...) \
163 __asm__ volatile( \
164 "mov %%fs:0, %%rax\n" \
165 "mov %P[tls](%%rax), %%rax\n" \
166 "test %%rax, %%rax\n" \
mwajdeczc80aafa2014-05-26 13:56:37 +0200167 "je 1f\n" \
Stephen Hines3e8fce42016-03-22 23:35:27 -0700168 "jmp *%P[api](%%rax)\n" \
mwajdeczc80aafa2014-05-26 13:56:37 +0200169 "1:\n" \
Stephen Hines3e8fce42016-03-22 23:35:27 -0700170 : \
mwajdeczc80aafa2014-05-26 13:56:37 +0200171 : [tls] "i" (TLS_SLOT_OPENGL_API*sizeof(void*)), \
172 [api] "i" (__builtin_offsetof(gl_hooks_t, gl._api)) \
Stephen Hines3e8fce42016-03-22 23:35:27 -0700173 : "cc", "%rdi", "%rsi", "%rdx", "%rcx", "%r8", "%r9", \
174 "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", \
175 "%xmm6", "%xmm7" \
176 );
177
178 #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE \
179 __asm__ volatile( \
180 "xor %%eax, %%eax\n" \
181 : \
182 : \
183 : "%eax" \
184 );
185
186 #define CALL_GL_API_INTERNAL_DO_RETURN \
187 __asm__ volatile( \
188 "retq\n" \
189 : \
190 : \
191 : \
192 );
mwajdeczc80aafa2014-05-26 13:56:37 +0200193
Duane Sand6701fbe2014-11-26 13:17:40 -0800194#elif defined(__mips64)
195
Stephen Hines3e8fce42016-03-22 23:35:27 -0700196 #define API_ENTRY(_api) __attribute__((naked,noinline)) _api
Duane Sand6701fbe2014-11-26 13:17:40 -0800197
Stephen Hines3e8fce42016-03-22 23:35:27 -0700198 // t0: $12
199 // fn: $25
200 // tls: $3
201 // v0: $2
202 #define CALL_GL_API_INTERNAL_CALL(_api, ...) \
203 asm volatile( \
204 ".set push\n\t" \
205 ".set noreorder\n\t" \
206 "rdhwr $3, $29\n\t" \
207 "ld $12, %[OPENGL_API]($3)\n\t" \
208 "beqz $12, 1f\n\t" \
209 " move $25, $ra\n\t" \
210 "ld $12, %[API]($12)\n\t" \
211 "beqz $12, 1f\n\t" \
212 " nop\n\t" \
213 "move $25, $12\n\t" \
214 "1:\n\t" \
215 "jalr $0, $25\n\t" \
216 " move $2, $0\n\t" \
217 ".set pop\n\t" \
218 : \
219 : [OPENGL_API] "I"(TLS_SLOT_OPENGL_API*sizeof(void*)),\
220 [API] "I"(__builtin_offsetof(gl_hooks_t, gl._api)) \
221 : "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9", \
222 "$10", "$11", "$12", "$25" \
Duane Sand6701fbe2014-11-26 13:17:40 -0800223 );
224
Stephen Hines3e8fce42016-03-22 23:35:27 -0700225 #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE
226 #define CALL_GL_API_INTERNAL_DO_RETURN
227
Jesse Hall30a41aa2014-05-30 23:32:12 -0700228#elif defined(__mips__)
Duane Sand46b42532013-03-27 10:58:06 -0700229
Stephen Hines3e8fce42016-03-22 23:35:27 -0700230 #define API_ENTRY(_api) __attribute__((naked,noinline)) _api
Duane Sand46b42532013-03-27 10:58:06 -0700231
Stephen Hines3e8fce42016-03-22 23:35:27 -0700232 // t0: $8
233 // fn: $25
234 // tls: $3
235 // v0: $2
236 #define CALL_GL_API_INTERNAL_CALL(_api, ...) \
Duane Sand46b42532013-03-27 10:58:06 -0700237 asm volatile( \
238 ".set push\n\t" \
239 ".set noreorder\n\t" \
Duane Sandecacc3f2015-02-02 16:54:15 -0800240 ".set mips32r2\n\t" \
Stephen Hines3e8fce42016-03-22 23:35:27 -0700241 "rdhwr $3, $29\n\t" \
242 "lw $3, %[OPENGL_API]($3)\n\t" \
243 "beqz $3, 1f\n\t" \
244 " move $25,$ra\n\t" \
245 "lw $3, %[API]($3)\n\t" \
246 "beqz $3, 1f\n\t" \
Duane Sand6701fbe2014-11-26 13:17:40 -0800247 " nop\n\t" \
Stephen Hines3e8fce42016-03-22 23:35:27 -0700248 "move $25, $3\n\t" \
Duane Sand46b42532013-03-27 10:58:06 -0700249 "1:\n\t" \
Stephen Hines3e8fce42016-03-22 23:35:27 -0700250 "jalr $0, $25\n\t" \
251 " move $2, $0\n\t" \
Duane Sand46b42532013-03-27 10:58:06 -0700252 ".set pop\n\t" \
Stephen Hines3e8fce42016-03-22 23:35:27 -0700253 : \
Duane Sand46b42532013-03-27 10:58:06 -0700254 : [OPENGL_API] "I"(TLS_SLOT_OPENGL_API*4), \
255 [API] "I"(__builtin_offsetof(gl_hooks_t, gl._api)) \
Stephen Hines3e8fce42016-03-22 23:35:27 -0700256 : "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$25" \
257 );
258
259 #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE
260 #define CALL_GL_API_INTERNAL_DO_RETURN
Duane Sand46b42532013-03-27 10:58:06 -0700261
Mathias Agopianb1a39d62009-05-27 20:38:06 -0700262#endif
263
Stephen Hines3e8fce42016-03-22 23:35:27 -0700264#define CALL_GL_API(_api, ...) \
265 CALL_GL_API_INTERNAL_CALL(_api, __VA_ARGS__) \
266 CALL_GL_API_INTERNAL_DO_RETURN
267
Mathias Agopiane0ea89c2013-06-14 19:08:36 -0700268#define CALL_GL_API_RETURN(_api, ...) \
Stephen Hines3e8fce42016-03-22 23:35:27 -0700269 CALL_GL_API_INTERNAL_CALL(_api, __VA_ARGS__) \
270 CALL_GL_API_INTERNAL_SET_RETURN_VALUE \
271 CALL_GL_API_INTERNAL_DO_RETURN
Mathias Agopianb1a39d62009-05-27 20:38:06 -0700272
273extern "C" {
Jesse Hallbbbddb82014-05-13 21:13:14 -0700274#pragma GCC diagnostic ignored "-Wunused-parameter"
Jesse Hall4c0596f2014-05-13 16:48:35 -0700275#include "gl2_api.in"
Mathias Agopianb1a39d62009-05-27 20:38:06 -0700276#include "gl2ext_api.in"
Jesse Hallbbbddb82014-05-13 21:13:14 -0700277#pragma GCC diagnostic warning "-Wunused-parameter"
Mathias Agopianb1a39d62009-05-27 20:38:06 -0700278}
279
280#undef API_ENTRY
281#undef CALL_GL_API
Stephen Hines3e8fce42016-03-22 23:35:27 -0700282#undef CALL_GL_API_INTERNAL_CALL
283#undef CALL_GL_API_INTERNAL_SET_RETURN_VALUE
284#undef CALL_GL_API_INTERNAL_DO_RETURN
Mathias Agopianb1a39d62009-05-27 20:38:06 -0700285#undef CALL_GL_API_RETURN
286
Mathias Agopian48d438d2012-01-28 21:44:00 -0800287/*
Alistair Strachanedfe72e2015-05-22 14:10:09 -0700288 * glGetString() and glGetStringi() are special because we expose some
289 * extensions in the wrapper. Also, wrapping glGetXXX() is required because
290 * the value returned for GL_NUM_EXTENSIONS may have been altered by the
291 * injection of the additional extensions.
Mathias Agopian48d438d2012-01-28 21:44:00 -0800292 */
293
Alistair Strachanedfe72e2015-05-22 14:10:09 -0700294extern "C" {
295 const GLubyte * __glGetString(GLenum name);
296 const GLubyte * __glGetStringi(GLenum name, GLuint index);
297 void __glGetBooleanv(GLenum pname, GLboolean * data);
298 void __glGetFloatv(GLenum pname, GLfloat * data);
299 void __glGetIntegerv(GLenum pname, GLint * data);
300 void __glGetInteger64v(GLenum pname, GLint64 * data);
301}
Mathias Agopian48d438d2012-01-28 21:44:00 -0800302
Alistair Strachanedfe72e2015-05-22 14:10:09 -0700303const GLubyte * glGetString(GLenum name) {
Cody Northrop68d10352018-10-15 07:22:09 -0600304 egl_connection_t* const cnx = egl_get_connection();
305 return cnx->platform.glGetString(name);
Mathias Agopian48d438d2012-01-28 21:44:00 -0800306}
Alistair Strachanedfe72e2015-05-22 14:10:09 -0700307
308const GLubyte * glGetStringi(GLenum name, GLuint index) {
Cody Northrop68d10352018-10-15 07:22:09 -0600309 egl_connection_t* const cnx = egl_get_connection();
310 return cnx->platform.glGetStringi(name, index);
Alistair Strachanedfe72e2015-05-22 14:10:09 -0700311}
312
313void glGetBooleanv(GLenum pname, GLboolean * data) {
Cody Northrop68d10352018-10-15 07:22:09 -0600314 egl_connection_t* const cnx = egl_get_connection();
315 return cnx->platform.glGetBooleanv(pname, data);
Alistair Strachanedfe72e2015-05-22 14:10:09 -0700316}
317
318void glGetFloatv(GLenum pname, GLfloat * data) {
Cody Northrop68d10352018-10-15 07:22:09 -0600319 egl_connection_t* const cnx = egl_get_connection();
320 return cnx->platform.glGetFloatv(pname, data);
Alistair Strachanedfe72e2015-05-22 14:10:09 -0700321}
322
323void glGetIntegerv(GLenum pname, GLint * data) {
Cody Northrop68d10352018-10-15 07:22:09 -0600324 egl_connection_t* const cnx = egl_get_connection();
325 return cnx->platform.glGetIntegerv(pname, data);
Alistair Strachanedfe72e2015-05-22 14:10:09 -0700326}
327
328void glGetInteger64v(GLenum pname, GLint64 * data) {
Cody Northrop68d10352018-10-15 07:22:09 -0600329 egl_connection_t* const cnx = egl_get_connection();
330 return cnx->platform.glGetInteger64v(pname, data);
Alistair Strachanedfe72e2015-05-22 14:10:09 -0700331}