1 /* 2 * Mesa 3-D graphics library 3 * Version: 7.9 4 * 5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 6 * Copyright (C) 2010 LunarG Inc. 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a 9 * copy of this software and associated documentation files (the "Software"), 10 * to deal in the Software without restriction, including without limitation 11 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 * and/or sell copies of the Software, and to permit persons to whom the 13 * Software is furnished to do so, subject to the following conditions: 14 * 15 * The above copyright notice and this permission notice shall be included 16 * in all copies or substantial portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 * DEALINGS IN THE SOFTWARE. 25 * 26 * Authors: 27 * Chia-I Wu <olv (at) lunarg.com> 28 */ 29 30 #include <string.h> 31 #include "glapi/glapi.h" 32 #include "mapi/u_current.h" 33 #include "mapi/table.h" /* for MAPI_TABLE_NUM_SLOTS */ 34 #include "mapi/stub.h" 35 36 /* 37 * Global variables, _glapi_get_context, and _glapi_get_dispatch are defined in 38 * u_current.c. 39 */ 40 41 #ifdef GLX_USE_TLS 42 /* not used, but defined for compatibility */ 43 const struct _glapi_table *_glapi_Dispatch; 44 const void *_glapi_Context; 45 #endif /* GLX_USE_TLS */ 46 47 void 48 _glapi_destroy_multithread(void) 49 { 50 u_current_destroy(); 51 } 52 53 void 54 _glapi_check_multithread(void) 55 { 56 u_current_init(); 57 } 58 59 void 60 _glapi_set_context(void *context) 61 { 62 u_current_set_user((const void *) context); 63 } 64 65 void 66 _glapi_set_dispatch(struct _glapi_table *dispatch) 67 { 68 u_current_set((const struct mapi_table *) dispatch); 69 } 70 71 /** 72 * Return size of dispatch table struct as number of functions (or 73 * slots). 74 */ 75 unsigned int 76 _glapi_get_dispatch_table_size(void) 77 { 78 return MAPI_TABLE_NUM_SLOTS; 79 } 80 81 /** 82 * Fill-in the dispatch stub for the named function. 83 * 84 * This function is intended to be called by a hardware driver. When called, 85 * a dispatch stub may be created created for the function. A pointer to this 86 * dispatch function will be returned by glXGetProcAddress. 87 * 88 * \param function_names Array of pointers to function names that should 89 * share a common dispatch offset. 90 * \param parameter_signature String representing the types of the parameters 91 * passed to the named function. Parameter types 92 * are converted to characters using the following 93 * rules: 94 * - 'i' for \c GLint, \c GLuint, and \c GLenum 95 * - 'p' for any pointer type 96 * - 'f' for \c GLfloat and \c GLclampf 97 * - 'd' for \c GLdouble and \c GLclampd 98 * 99 * \returns 100 * The offset in the dispatch table of the named function. A pointer to the 101 * driver's implementation of the named function should be stored at 102 * \c dispatch_table[\c offset]. Return -1 if error/problem. 103 * 104 * \sa glXGetProcAddress 105 * 106 * \warning 107 * This function can only handle up to 8 names at a time. As far as I know, 108 * the maximum number of names ever associated with an existing GL function is 109 * 4 (\c glPointParameterfSGIS, \c glPointParameterfEXT, 110 * \c glPointParameterfARB, and \c glPointParameterf), so this should not be 111 * too painful of a limitation. 112 * 113 * \todo 114 * Check parameter_signature. 115 */ 116 int 117 _glapi_add_dispatch( const char * const * function_names, 118 const char * parameter_signature ) 119 { 120 const struct mapi_stub *function_stubs[8]; 121 const struct mapi_stub *alias = NULL; 122 unsigned i; 123 124 (void) memset(function_stubs, 0, sizeof(function_stubs)); 125 126 /* find the missing stubs, and decide the alias */ 127 for (i = 0; function_names[i] != NULL && i < 8; i++) { 128 const char * funcName = function_names[i]; 129 const struct mapi_stub *stub; 130 int slot; 131 132 if (!funcName || funcName[0] != 'g' || funcName[1] != 'l') 133 return -1; 134 funcName += 2; 135 136 stub = stub_find_public(funcName); 137 if (!stub) 138 stub = stub_find_dynamic(funcName, 0); 139 140 slot = (stub) ? stub_get_slot(stub) : -1; 141 if (slot >= 0) { 142 if (alias && stub_get_slot(alias) != slot) 143 return -1; 144 /* use the first existing stub as the alias */ 145 if (!alias) 146 alias = stub; 147 148 function_stubs[i] = stub; 149 } 150 } 151 152 /* generate missing stubs */ 153 for (i = 0; function_names[i] != NULL && i < 8; i++) { 154 const char * funcName = function_names[i] + 2; 155 struct mapi_stub *stub; 156 157 if (function_stubs[i]) 158 continue; 159 160 stub = stub_find_dynamic(funcName, 1); 161 if (!stub) 162 return -1; 163 164 stub_fix_dynamic(stub, alias); 165 if (!alias) 166 alias = stub; 167 } 168 169 return (alias) ? stub_get_slot(alias) : -1; 170 } 171 172 static const struct mapi_stub * 173 _glapi_get_stub(const char *name, int generate) 174 { 175 const struct mapi_stub *stub; 176 177 #ifdef USE_MGL_NAMESPACE 178 if (name) 179 name++; 180 #endif 181 182 if (!name || name[0] != 'g' || name[1] != 'l') 183 return NULL; 184 name += 2; 185 186 stub = stub_find_public(name); 187 if (!stub) 188 stub = stub_find_dynamic(name, generate); 189 190 return stub; 191 } 192 193 /** 194 * Return offset of entrypoint for named function within dispatch table. 195 */ 196 int 197 _glapi_get_proc_offset(const char *funcName) 198 { 199 const struct mapi_stub *stub = _glapi_get_stub(funcName, 0); 200 return (stub) ? stub_get_slot(stub) : -1; 201 } 202 203 /** 204 * Return pointer to the named function. If the function name isn't found 205 * in the name of static functions, try generating a new API entrypoint on 206 * the fly with assembly language. 207 */ 208 _glapi_proc 209 _glapi_get_proc_address(const char *funcName) 210 { 211 const struct mapi_stub *stub = _glapi_get_stub(funcName, 1); 212 return (stub) ? (_glapi_proc) stub_get_addr(stub) : NULL; 213 } 214 215 /** 216 * Return the name of the function at the given dispatch offset. 217 * This is only intended for debugging. 218 */ 219 const char * 220 _glapi_get_proc_name(unsigned int offset) 221 { 222 /* not implemented */ 223 return NULL; 224 } 225 226 unsigned long 227 _glthread_GetID(void) 228 { 229 return u_thread_self(); 230 } 231 232 void 233 _glapi_noop_enable_warnings(unsigned char enable) 234 { 235 } 236 237 void 238 _glapi_set_warning_func(_glapi_proc func) 239 { 240 } 241