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 defined(__arm__) && !USE_SLOW_BINDING 96 97 #define GET_TLS(reg) "mrc p15, 0, " #reg ", c13, c0, 3 \n" 98 99 #define API_ENTRY(_api) __attribute__((noinline)) _api 100 101 #define CALL_GL_API(_api, ...) \ 102 asm volatile( \ 103 GET_TLS(r12) \ 104 "ldr r12, [r12, %[tls]] \n" \ 105 "cmp r12, #0 \n" \ 106 "ldrne pc, [r12, %[api]] \n" \ 107 : \ 108 : [tls] "J"(TLS_SLOT_OPENGL_API*4), \ 109 [api] "J"(__builtin_offsetof(gl_hooks_t, gl._api)) \ 110 : \ 111 ); 112 113 #elif defined(__mips__) && !USE_SLOW_BINDING 114 115 #define API_ENTRY(_api) __attribute__((noinline)) _api 116 117 #define CALL_GL_API(_api, ...) \ 118 register unsigned int _t0 asm("t0"); \ 119 register unsigned int _fn asm("t1"); \ 120 register unsigned int _tls asm("v1"); \ 121 register unsigned int _v0 asm("v0"); \ 122 asm volatile( \ 123 ".set push\n\t" \ 124 ".set noreorder\n\t" \ 125 ".set mips32r2\n\t" \ 126 "rdhwr %[tls], $29\n\t" \ 127 "lw %[t0], %[OPENGL_API](%[tls])\n\t" \ 128 "beqz %[t0], 1f\n\t" \ 129 " move %[fn], $ra\n\t" \ 130 "lw %[fn], %[API](%[t0])\n\t" \ 131 "movz %[fn], $ra, %[fn]\n\t" \ 132 "1:\n\t" \ 133 "j %[fn]\n\t" \ 134 " move %[v0], $0\n\t" \ 135 ".set pop\n\t" \ 136 : [fn] "=c"(_fn), \ 137 [tls] "=&r"(_tls), \ 138 [t0] "=&r"(_t0), \ 139 [v0] "=&r"(_v0) \ 140 : [OPENGL_API] "I"(TLS_SLOT_OPENGL_API*4), \ 141 [API] "I"(__builtin_offsetof(gl_hooks_t, gl._api)) \ 142 : \ 143 ); 144 145 #else 146 147 #define API_ENTRY(_api) _api 148 149 #define CALL_GL_API(_api, ...) \ 150 gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \ 151 if (_c) return _c->_api(__VA_ARGS__); 152 153 #endif 154 155 #define CALL_GL_API_RETURN(_api, ...) \ 156 CALL_GL_API(_api, __VA_ARGS__) \ 157 return 0; 158 159 160 extern "C" { 161 #include "gl_api.in" 162 #include "glext_api.in" 163 } 164 165 #undef API_ENTRY 166 #undef CALL_GL_API 167 #undef CALL_GL_API_RETURN 168 169 /* 170 * glGetString() is special because we expose some extensions in the wrapper 171 */ 172 173 extern "C" const GLubyte * __glGetString(GLenum name); 174 175 const GLubyte * glGetString(GLenum name) { 176 const GLubyte * ret = egl_get_string_for_current_context(name); 177 if (ret == NULL) { 178 gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; 179 ret = _c->glGetString(name); 180 } 181 return ret; 182 } 183