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