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     #ifdef HAVE_ARM_TLS_REGISTER
    101         #define GET_TLS(reg) \
    102             "mrc p15, 0, " #reg ", c13, c0, 3 \n"
    103     #else
    104         #define GET_TLS(reg) \
    105             "mov   " #reg ", #0xFFFF0FFF      \n"  \
    106             "ldr   " #reg ", [" #reg ", #-15] \n"
    107     #endif
    108 
    109     #define API_ENTRY(_api) __attribute__((naked)) _api
    110 
    111     #define CALL_GL_API(_api, ...)                              \
    112          asm volatile(                                          \
    113             GET_TLS(r12)                                        \
    114             "ldr   r12, [r12, %[tls]] \n"                       \
    115             "cmp   r12, #0            \n"                       \
    116             "ldrne pc,  [r12, %[api]] \n"                       \
    117             "mov   r0, #0             \n"                       \
    118             "bx    lr                 \n"                       \
    119             :                                                   \
    120             : [tls] "J"(TLS_SLOT_OPENGL_API*4),                 \
    121               [api] "J"(__builtin_offsetof(gl_hooks_t, gl._api))    \
    122             :                                                   \
    123             );
    124 
    125     #define CALL_GL_API_RETURN(_api, ...) \
    126         CALL_GL_API(_api, __VA_ARGS__) \
    127         return 0; // placate gcc's warnings. never reached.
    128 
    129 #else
    130 
    131     #if CHECK_FOR_GL_ERRORS
    132 
    133         #define CHECK_GL_ERRORS(_api) \
    134             do { GLint err = glGetError(); \
    135                 ALOGE_IF(err != GL_NO_ERROR, "%s failed (0x%04X)", #_api, err); \
    136             } while(false);
    137 
    138     #else
    139 
    140         #define CHECK_GL_ERRORS(_api) do { } while(false);
    141 
    142     #endif
    143 
    144 
    145     #define API_ENTRY(_api) _api
    146 
    147     #define CALL_GL_API(_api, ...)                                      \
    148         gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \
    149         _c->_api(__VA_ARGS__);                                          \
    150         CHECK_GL_ERRORS(_api)
    151 
    152     #define CALL_GL_API_RETURN(_api, ...)                               \
    153         gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \
    154         return _c->_api(__VA_ARGS__)
    155 
    156 #endif
    157 
    158 
    159 extern "C" {
    160 #include "gl_api.in"
    161 #include "glext_api.in"
    162 }
    163 
    164 #undef API_ENTRY
    165 #undef CALL_GL_API
    166 #undef CALL_GL_API_RETURN
    167 
    168 /*
    169  * glGetString() is special because we expose some extensions in the wrapper
    170  */
    171 
    172 extern "C" const GLubyte * __glGetString(GLenum name);
    173 
    174 const GLubyte * glGetString(GLenum name)
    175 {
    176     const GLubyte * ret = egl_get_string_for_current_context(name);
    177     if (ret == NULL) {
    178         ret = __glGetString(name);
    179     }
    180     return ret;
    181 }
    182