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