Home | History | Annotate | Download | only in GLES_CM
      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 
     54 void glColorPointerBounds(GLint size, GLenum type, GLsizei stride,
     55         const GLvoid *ptr, GLsizei /*count*/) {
     56     glColorPointer(size, type, stride, ptr);
     57 }
     58 void glNormalPointerBounds(GLenum type, GLsizei stride,
     59         const GLvoid *pointer, GLsizei /*count*/) {
     60     glNormalPointer(type, stride, pointer);
     61 }
     62 void glTexCoordPointerBounds(GLint size, GLenum type,
     63         GLsizei stride, const GLvoid *pointer, GLsizei /*count*/) {
     64     glTexCoordPointer(size, type, stride, pointer);
     65 }
     66 void glVertexPointerBounds(GLint size, GLenum type,
     67         GLsizei stride, const GLvoid *pointer, GLsizei /*count*/) {
     68     glVertexPointer(size, type, stride, pointer);
     69 }
     70 
     71 void GL_APIENTRY glPointSizePointerOESBounds(GLenum type,
     72         GLsizei stride, const GLvoid *pointer, GLsizei /*count*/) {
     73     glPointSizePointerOES(type, stride, pointer);
     74 }
     75 
     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 
     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(__mips64)
    251 
    252     #define API_ENTRY(_api) __attribute__((naked,noinline)) _api
    253 
    254     // t0:  $12
    255     // fn:  $25
    256     // tls: $3
    257     // v0:  $2
    258     #define CALL_GL_API_INTERNAL_CALL(_api, ...)                  \
    259         asm volatile(                                             \
    260             ".set  push\n\t"                                      \
    261             ".set  noreorder\n\t"                                 \
    262             "rdhwr $3, $29\n\t"                                   \
    263             "ld    $12, %[OPENGL_API]($3)\n\t"                    \
    264             "beqz  $12, 1f\n\t"                                   \
    265             " move $25, $ra\n\t"                                  \
    266             "ld    $12, %[API]($12)\n\t"                          \
    267             "beqz  $12, 1f\n\t"                                   \
    268             " nop\n\t"                                            \
    269             "move  $25, $12\n\t"                                  \
    270             "1:\n\t"                                              \
    271             "jalr  $0, $25\n\t"                                   \
    272             " move $2, $0\n\t"                                    \
    273             ".set  pop\n\t"                                       \
    274             :                                                     \
    275             : [OPENGL_API] "I"(TLS_SLOT_OPENGL_API*sizeof(void*)),\
    276               [API] "I"(__builtin_offsetof(gl_hooks_t, gl._api))  \
    277             : "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9",     \
    278               "$10", "$11", "$12", "$25"                          \
    279         );
    280 
    281     #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE
    282     #define CALL_GL_API_INTERNAL_DO_RETURN
    283 
    284 #elif defined(__mips__)
    285 
    286     #define API_ENTRY(_api) __attribute__((naked,noinline)) _api
    287 
    288     // t0:  $8
    289     // fn:  $25
    290     // tls: $3
    291     // v0:  $2
    292     #define CALL_GL_API_INTERNAL_CALL(_api, ...)                 \
    293         asm volatile(                                            \
    294             ".set  push\n\t"                                     \
    295             ".set  noreorder\n\t"                                \
    296             ".set  mips32r2\n\t"                                 \
    297             "rdhwr $3, $29\n\t"                                  \
    298             "lw    $3, %[OPENGL_API]($3)\n\t"                    \
    299             "beqz  $3, 1f\n\t"                                   \
    300             " move $25,$ra\n\t"                                  \
    301             "lw    $3, %[API]($3)\n\t"                           \
    302             "beqz  $3, 1f\n\t"                                   \
    303             " nop\n\t"                                           \
    304             "move  $25, $3\n\t"                                  \
    305             "1:\n\t"                                             \
    306             "jalr  $0, $25\n\t"                                  \
    307             " move $2, $0\n\t"                                   \
    308             ".set  pop\n\t"                                      \
    309             :                                                    \
    310             : [OPENGL_API] "I"(TLS_SLOT_OPENGL_API*4),           \
    311               [API] "I"(__builtin_offsetof(gl_hooks_t, gl._api)) \
    312             : "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$25"    \
    313         );
    314 
    315     #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE
    316     #define CALL_GL_API_INTERNAL_DO_RETURN
    317 
    318 #endif
    319 
    320 #define CALL_GL_API(_api, ...) \
    321     CALL_GL_API_INTERNAL_CALL(_api, __VA_ARGS__) \
    322     CALL_GL_API_INTERNAL_DO_RETURN
    323 
    324 #define CALL_GL_API_RETURN(_api, ...) \
    325     CALL_GL_API_INTERNAL_CALL(_api, __VA_ARGS__) \
    326     CALL_GL_API_INTERNAL_SET_RETURN_VALUE \
    327     CALL_GL_API_INTERNAL_DO_RETURN
    328 
    329 extern "C" {
    330 #pragma GCC diagnostic ignored "-Wunused-parameter"
    331 #include "gl_api.in"
    332 #include "glext_api.in"
    333 #pragma GCC diagnostic warning "-Wunused-parameter"
    334 }
    335 
    336 #undef API_ENTRY
    337 #undef CALL_GL_API
    338 #undef CALL_GL_API_INTERNAL_CALL
    339 #undef CALL_GL_API_INTERNAL_SET_RETURN_VALUE
    340 #undef CALL_GL_API_INTERNAL_DO_RETURN
    341 #undef CALL_GL_API_RETURN
    342 
    343 /*
    344  * glGetString() is special because we expose some extensions in the wrapper
    345  */
    346 
    347 extern "C" const GLubyte * __glGetString(GLenum name);
    348 
    349 const GLubyte * glGetString(GLenum name) {
    350     const GLubyte * ret = egl_get_string_for_current_context(name);
    351     if (ret == NULL) {
    352         gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;
    353         ret = _c->glGetString(name);
    354     }
    355     return ret;
    356 }
    357