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 55 void glColorPointerBounds(GLint size, GLenum type, GLsizei stride, 56 const GLvoid *ptr, GLsizei /*count*/) { 57 glColorPointer(size, type, stride, ptr); 58 } 59 void glNormalPointerBounds(GLenum type, GLsizei stride, 60 const GLvoid *pointer, GLsizei /*count*/) { 61 glNormalPointer(type, stride, pointer); 62 } 63 void glTexCoordPointerBounds(GLint size, GLenum type, 64 GLsizei stride, const GLvoid *pointer, GLsizei /*count*/) { 65 glTexCoordPointer(size, type, stride, pointer); 66 } 67 void glVertexPointerBounds(GLint size, GLenum type, 68 GLsizei stride, const GLvoid *pointer, GLsizei /*count*/) { 69 glVertexPointer(size, type, stride, pointer); 70 } 71 72 void GL_APIENTRY glPointSizePointerOESBounds(GLenum type, 73 GLsizei stride, const GLvoid *pointer, GLsizei /*count*/) { 74 glPointSizePointerOES(type, stride, pointer); 75 } 76 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 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 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