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 <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 // set this to 1 for crude GL debugging
     35 #define CHECK_FOR_GL_ERRORS     0
     36 
     37 // ----------------------------------------------------------------------------
     38 // extensions for the framework
     39 // ----------------------------------------------------------------------------
     40 
     41 extern "C" {
     42 GL_API void GL_APIENTRY glColorPointerBounds(GLint size, GLenum type, GLsizei stride,
     43         const GLvoid *ptr, GLsizei count);
     44 GL_API void GL_APIENTRY glNormalPointerBounds(GLenum type, GLsizei stride,
     45         const GLvoid *pointer, GLsizei count);
     46 GL_API void GL_APIENTRY glTexCoordPointerBounds(GLint size, GLenum type,
     47         GLsizei stride, const GLvoid *pointer, GLsizei count);
     48 GL_API void GL_APIENTRY glVertexPointerBounds(GLint size, GLenum type,
     49         GLsizei stride, const GLvoid *pointer, GLsizei count);
     50 GL_API void GL_APIENTRY glPointSizePointerOESBounds(GLenum type,
     51         GLsizei stride, const GLvoid *pointer, GLsizei count);
     52 GL_API void GL_APIENTRY glMatrixIndexPointerOESBounds(GLint size, GLenum type,
     53         GLsizei stride, const GLvoid *pointer, GLsizei count);
     54 GL_API void GL_APIENTRY glWeightPointerOESBounds(GLint size, GLenum type,
     55         GLsizei stride, const GLvoid *pointer, GLsizei count);
     56 }
     57 
     58 void glColorPointerBounds(GLint size, GLenum type, GLsizei stride,
     59         const GLvoid *ptr, GLsizei count) {
     60     glColorPointer(size, type, stride, ptr);
     61 }
     62 void glNormalPointerBounds(GLenum type, GLsizei stride,
     63         const GLvoid *pointer, GLsizei count) {
     64     glNormalPointer(type, stride, pointer);
     65 }
     66 void glTexCoordPointerBounds(GLint size, GLenum type,
     67         GLsizei stride, const GLvoid *pointer, GLsizei count) {
     68     glTexCoordPointer(size, type, stride, pointer);
     69 }
     70 void glVertexPointerBounds(GLint size, GLenum type,
     71         GLsizei stride, const GLvoid *pointer, GLsizei count) {
     72     glVertexPointer(size, type, stride, pointer);
     73 }
     74 
     75 void GL_APIENTRY glPointSizePointerOESBounds(GLenum type,
     76         GLsizei stride, const GLvoid *pointer, GLsizei count) {
     77     glPointSizePointerOES(type, stride, pointer);
     78 }
     79 
     80 GL_API void GL_APIENTRY glMatrixIndexPointerOESBounds(GLint size, GLenum type,
     81         GLsizei stride, const GLvoid *pointer, GLsizei count) {
     82     glMatrixIndexPointerOES(size, type, stride, pointer);
     83 }
     84 
     85 GL_API void GL_APIENTRY glWeightPointerOESBounds(GLint size, GLenum type,
     86         GLsizei stride, const GLvoid *pointer, GLsizei count) {
     87     glWeightPointerOES(size, type, stride, pointer);
     88 }
     89 
     90 // ----------------------------------------------------------------------------
     91 // Actual GL entry-points
     92 // ----------------------------------------------------------------------------
     93 
     94 #undef API_ENTRY
     95 #undef CALL_GL_API
     96 #undef CALL_GL_API_RETURN
     97 
     98 #if USE_FAST_TLS_KEY && !CHECK_FOR_GL_ERRORS
     99 
    100   #if defined(__arm__)
    101 
    102     #define GET_TLS(reg) "mrc p15, 0, " #reg ", c13, c0, 3 \n"
    103 
    104     #define API_ENTRY(_api) __attribute__((naked)) _api
    105 
    106     #define CALL_GL_API(_api, ...)                              \
    107          asm volatile(                                          \
    108             GET_TLS(r12)                                        \
    109             "ldr   r12, [r12, %[tls]] \n"                       \
    110             "cmp   r12, #0            \n"                       \
    111             "ldrne pc,  [r12, %[api]] \n"                       \
    112             "mov   r0, #0             \n"                       \
    113             "bx    lr                 \n"                       \
    114             :                                                   \
    115             : [tls] "J"(TLS_SLOT_OPENGL_API*4),                 \
    116               [api] "J"(__builtin_offsetof(gl_hooks_t, gl._api))    \
    117             :                                                   \
    118             );
    119 
    120   #elif defined(__mips__)
    121 
    122     #define API_ENTRY(_api) __attribute__((noinline)) _api
    123 
    124     #define CALL_GL_API(_api, ...)                               \
    125         register unsigned int _t0 asm("t0");                     \
    126         register unsigned int _fn asm("t1");                     \
    127         register unsigned int _tls asm("v1");                    \
    128         register unsigned int _v0 asm("v0");                     \
    129         asm volatile(                                            \
    130             ".set  push\n\t"                                     \
    131             ".set  noreorder\n\t"                                \
    132             ".set  mips32r2\n\t"                                 \
    133             "rdhwr %[tls], $29\n\t"                              \
    134             "lw    %[t0], %[OPENGL_API](%[tls])\n\t"             \
    135             "beqz  %[t0], 1f\n\t"                                \
    136             " move %[fn], $ra\n\t"                               \
    137             "lw    %[fn], %[API](%[t0])\n\t"                     \
    138             "movz  %[fn], $ra, %[fn]\n\t"                        \
    139             "1:\n\t"                                             \
    140             "j     %[fn]\n\t"                                    \
    141             " move %[v0], $0\n\t"                                \
    142             ".set  pop\n\t"                                      \
    143             : [fn] "=c"(_fn),                                    \
    144               [tls] "=&r"(_tls),                                 \
    145               [t0] "=&r"(_t0),                                   \
    146               [v0] "=&r"(_v0)                                    \
    147             : [OPENGL_API] "I"(TLS_SLOT_OPENGL_API*4),           \
    148               [API] "I"(__builtin_offsetof(gl_hooks_t, gl._api)) \
    149             :                                                    \
    150             );
    151 
    152   #else
    153     #error Unsupported architecture
    154   #endif
    155 
    156     #define CALL_GL_API_RETURN(_api, ...) \
    157         CALL_GL_API(_api, __VA_ARGS__) \
    158         return 0; // placate gcc's warnings. never reached.
    159 
    160 #else
    161 
    162     #if CHECK_FOR_GL_ERRORS
    163 
    164         #define CHECK_GL_ERRORS(_api) \
    165             do { GLint err = glGetError(); \
    166                 ALOGE_IF(err != GL_NO_ERROR, "%s failed (0x%04X)", #_api, err); \
    167             } while(false);
    168 
    169     #else
    170 
    171         #define CHECK_GL_ERRORS(_api) do { } while(false);
    172 
    173     #endif
    174 
    175 
    176     #define API_ENTRY(_api) _api
    177 
    178     #define CALL_GL_API(_api, ...)                                      \
    179         gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \
    180         _c->_api(__VA_ARGS__);                                          \
    181         CHECK_GL_ERRORS(_api)
    182 
    183     #define CALL_GL_API_RETURN(_api, ...)                               \
    184         gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \
    185         return _c->_api(__VA_ARGS__)
    186 
    187 #endif
    188 
    189 
    190 extern "C" {
    191 #include "gl_api.in"
    192 #include "glext_api.in"
    193 }
    194 
    195 #undef API_ENTRY
    196 #undef CALL_GL_API
    197 #undef CALL_GL_API_RETURN
    198 
    199 /*
    200  * glGetString() is special because we expose some extensions in the wrapper
    201  */
    202 
    203 extern "C" const GLubyte * __glGetString(GLenum name);
    204 
    205 const GLubyte * glGetString(GLenum name)
    206 {
    207     const GLubyte * ret = egl_get_string_for_current_context(name);
    208     if (ret == NULL) {
    209         ret = __glGetString(name);
    210     }
    211     return ret;
    212 }
    213