Home | History | Annotate | Download | only in egl
      1 /*
      2 * Copyright (C) 2011 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 #include "ClientAPIExts.h"
     17 #include "ThreadInfo.h"
     18 #include <GLES/gl.h>
     19 #include <GLES/glext.h>
     20 #include "eglContext.h"
     21 
     22 namespace ClientAPIExts
     23 {
     24 
     25 //
     26 // define function pointer type for each extention function
     27 // typename has the form __egl_{funcname}_t
     28 //
     29 #define FUNC_TYPE(fname) __egl_ ## fname ## _t
     30 #define API_ENTRY(fname,params,args) \
     31     typedef void (GL_APIENTRY *FUNC_TYPE(fname)) params;
     32 
     33 #define API_ENTRY_RET(rtype,fname,params,args) \
     34     typedef rtype (GL_APIENTRY *FUNC_TYPE(fname)) params;
     35 
     36 #include "ClientAPIExts.in"
     37 #undef API_ENTRY
     38 #undef API_ENTRY_RET
     39 
     40 /////
     41 // Define static table to store the function value for each
     42 // client API. functions pointers will get initialized through
     43 // ClientAPIExts::initClientFuncs function after each client API has been
     44 // loaded.
     45 /////
     46 #define API_ENTRY(fname,params,args) \
     47     FUNC_TYPE(fname) fname;
     48 
     49 #define API_ENTRY_RET(rtype,fname,params,args) \
     50     API_ENTRY(fname,params,args)
     51 
     52 static struct _ext_table
     53 {
     54 #include "ClientAPIExts.in"
     55 } s_client_extensions[2];
     56 
     57 #undef API_ENTRY
     58 #undef API_ENTRY_RET
     59 
     60 //
     61 // This function initialized each entry in the s_client_extensions
     62 // struct at the givven index using the givven client interface
     63 //
     64 void initClientFuncs(const EGLClient_glesInterface *iface, int idx)
     65 {
     66 #define API_ENTRY(fname,params,args) \
     67     s_client_extensions[idx].fname = \
     68           (FUNC_TYPE(fname))iface->getProcAddress(#fname);
     69 
     70 #define API_ENTRY_RET(rtype,fname,params,args) \
     71     API_ENTRY(fname,params,args)
     72 
     73     //
     74     // reset all func pointers to NULL
     75     //
     76     memset(&s_client_extensions[idx], 0, sizeof(struct _ext_table));
     77 
     78     //
     79     // And now query the GLES library for each proc address
     80     //
     81 #include "ClientAPIExts.in"
     82 #undef API_ENTRY
     83 #undef API_ENTRY_RET
     84 }
     85 
     86 //
     87 // Define implementation for each extension function which checks
     88 // the current context version and calls to the correct client API
     89 // function.
     90 //
     91 #define API_ENTRY(fname,params,args) \
     92     static void _egl_ ## fname params \
     93     { \
     94         EGLThreadInfo* thread  = getEGLThreadInfo(); \
     95         if (!thread->currentContext) { \
     96             return; \
     97         } \
     98         int idx = (int)thread->currentContext->version - 1; \
     99         if (!s_client_extensions[idx].fname) { \
    100             return; \
    101         } \
    102         (*s_client_extensions[idx].fname) args; \
    103     }
    104 
    105 #define API_ENTRY_RET(rtype,fname,params,args) \
    106     static rtype _egl_ ## fname params \
    107     { \
    108         EGLThreadInfo* thread  = getEGLThreadInfo(); \
    109         if (!thread->currentContext) { \
    110             return (rtype)0; \
    111         } \
    112         int idx = (int)thread->currentContext->version - 1; \
    113         if (!s_client_extensions[idx].fname) { \
    114             return (rtype)0; \
    115         } \
    116         return (*s_client_extensions[idx].fname) args; \
    117     }
    118 
    119 #include "ClientAPIExts.in"
    120 #undef API_ENTRY
    121 #undef API_ENTRY_RET
    122 
    123 //
    124 // Define a table to map function names to the local _egl_ version of
    125 // the extension function, to be used in eglGetProcAddress.
    126 //
    127 #define API_ENTRY(fname,params,args) \
    128     { #fname, (void*)_egl_ ## fname},
    129 #define API_ENTRY_RET(rtype,fname,params,args) \
    130     API_ENTRY(fname,params,args)
    131 
    132 static const struct _client_ext_funcs {
    133     const char *fname;
    134     void* proc;
    135 } s_client_ext_funcs[] = {
    136 #include "ClientAPIExts.in"
    137 };
    138 static const int numExtFuncs = sizeof(s_client_ext_funcs) /
    139                                sizeof(s_client_ext_funcs[0]);
    140 
    141 #undef API_ENTRY
    142 #undef API_ENTRY_RET
    143 
    144 //
    145 // returns the __egl_ version of the givven extension function name.
    146 //
    147 void* getProcAddress(const char *fname)
    148 {
    149     for (int i=0; i<numExtFuncs; i++) {
    150         if (!strcmp(fname, s_client_ext_funcs[i].fname)) {
    151             return s_client_ext_funcs[i].proc;
    152         }
    153     }
    154     return NULL;
    155 }
    156 
    157 } // of namespace ClientAPIExts
    158