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