mapi_glapi.c revision 848b8605
1848b8605Smrg/* 2848b8605Smrg * Mesa 3-D graphics library 3848b8605Smrg * 4848b8605Smrg * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 5848b8605Smrg * Copyright (C) 2010 LunarG Inc. 6848b8605Smrg * 7848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 8848b8605Smrg * copy of this software and associated documentation files (the "Software"), 9848b8605Smrg * to deal in the Software without restriction, including without limitation 10848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the 12848b8605Smrg * Software is furnished to do so, subject to the following conditions: 13848b8605Smrg * 14848b8605Smrg * The above copyright notice and this permission notice shall be included 15848b8605Smrg * in all copies or substantial portions of the Software. 16848b8605Smrg * 17848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18848b8605Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21848b8605Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22848b8605Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23848b8605Smrg * DEALINGS IN THE SOFTWARE. 24848b8605Smrg * 25848b8605Smrg * Authors: 26848b8605Smrg * Chia-I Wu <olv@lunarg.com> 27848b8605Smrg */ 28848b8605Smrg 29848b8605Smrg#include <string.h> 30848b8605Smrg#include "glapi/glapi.h" 31848b8605Smrg#include "u_current.h" 32848b8605Smrg#include "table.h" /* for MAPI_TABLE_NUM_SLOTS */ 33848b8605Smrg#include "stub.h" 34848b8605Smrg 35848b8605Smrg/* 36848b8605Smrg * Global variables, _glapi_get_context, and _glapi_get_dispatch are defined in 37848b8605Smrg * u_current.c. 38848b8605Smrg */ 39848b8605Smrg 40848b8605Smrg#ifdef GLX_USE_TLS 41848b8605Smrg/* not used, but defined for compatibility */ 42848b8605Smrgconst struct _glapi_table *_glapi_Dispatch; 43848b8605Smrgconst void *_glapi_Context; 44848b8605Smrg#endif /* GLX_USE_TLS */ 45848b8605Smrg 46848b8605Smrgvoid 47848b8605Smrg_glapi_destroy_multithread(void) 48848b8605Smrg{ 49848b8605Smrg u_current_destroy(); 50848b8605Smrg} 51848b8605Smrg 52848b8605Smrgvoid 53848b8605Smrg_glapi_check_multithread(void) 54848b8605Smrg{ 55848b8605Smrg u_current_init(); 56848b8605Smrg} 57848b8605Smrg 58848b8605Smrgvoid 59848b8605Smrg_glapi_set_context(void *context) 60848b8605Smrg{ 61848b8605Smrg u_current_set_context((const void *) context); 62848b8605Smrg} 63848b8605Smrg 64848b8605Smrgvoid 65848b8605Smrg_glapi_set_dispatch(struct _glapi_table *dispatch) 66848b8605Smrg{ 67848b8605Smrg u_current_set_table((const struct mapi_table *) dispatch); 68848b8605Smrg} 69848b8605Smrg 70848b8605Smrg/** 71848b8605Smrg * Return size of dispatch table struct as number of functions (or 72848b8605Smrg * slots). 73848b8605Smrg */ 74848b8605Smrgunsigned int 75848b8605Smrg_glapi_get_dispatch_table_size(void) 76848b8605Smrg{ 77848b8605Smrg return MAPI_TABLE_NUM_SLOTS; 78848b8605Smrg} 79848b8605Smrg 80848b8605Smrg/** 81848b8605Smrg * Fill-in the dispatch stub for the named function. 82848b8605Smrg * 83848b8605Smrg * This function is intended to be called by a hardware driver. When called, 84848b8605Smrg * a dispatch stub may be created created for the function. A pointer to this 85848b8605Smrg * dispatch function will be returned by glXGetProcAddress. 86848b8605Smrg * 87848b8605Smrg * \param function_names Array of pointers to function names that should 88848b8605Smrg * share a common dispatch offset. 89848b8605Smrg * \param parameter_signature String representing the types of the parameters 90848b8605Smrg * passed to the named function. Parameter types 91848b8605Smrg * are converted to characters using the following 92848b8605Smrg * rules: 93848b8605Smrg * - 'i' for \c GLint, \c GLuint, and \c GLenum 94848b8605Smrg * - 'p' for any pointer type 95848b8605Smrg * - 'f' for \c GLfloat and \c GLclampf 96848b8605Smrg * - 'd' for \c GLdouble and \c GLclampd 97848b8605Smrg * 98848b8605Smrg * \returns 99848b8605Smrg * The offset in the dispatch table of the named function. A pointer to the 100848b8605Smrg * driver's implementation of the named function should be stored at 101848b8605Smrg * \c dispatch_table[\c offset]. Return -1 if error/problem. 102848b8605Smrg * 103848b8605Smrg * \sa glXGetProcAddress 104848b8605Smrg * 105848b8605Smrg * \warning 106848b8605Smrg * This function can only handle up to 8 names at a time. As far as I know, 107848b8605Smrg * the maximum number of names ever associated with an existing GL function is 108848b8605Smrg * 4 (\c glPointParameterfSGIS, \c glPointParameterfEXT, 109848b8605Smrg * \c glPointParameterfARB, and \c glPointParameterf), so this should not be 110848b8605Smrg * too painful of a limitation. 111848b8605Smrg * 112848b8605Smrg * \todo 113848b8605Smrg * Check parameter_signature. 114848b8605Smrg */ 115848b8605Smrgint 116848b8605Smrg_glapi_add_dispatch( const char * const * function_names, 117848b8605Smrg const char * parameter_signature ) 118848b8605Smrg{ 119848b8605Smrg const struct mapi_stub *function_stubs[8]; 120848b8605Smrg const struct mapi_stub *alias = NULL; 121848b8605Smrg unsigned i; 122848b8605Smrg 123848b8605Smrg (void) memset(function_stubs, 0, sizeof(function_stubs)); 124848b8605Smrg 125848b8605Smrg /* find the missing stubs, and decide the alias */ 126848b8605Smrg for (i = 0; function_names[i] != NULL && i < 8; i++) { 127848b8605Smrg const char * funcName = function_names[i]; 128848b8605Smrg const struct mapi_stub *stub; 129848b8605Smrg int slot; 130848b8605Smrg 131848b8605Smrg if (!funcName || funcName[0] != 'g' || funcName[1] != 'l') 132848b8605Smrg return -1; 133848b8605Smrg funcName += 2; 134848b8605Smrg 135848b8605Smrg stub = stub_find_public(funcName); 136848b8605Smrg if (!stub) 137848b8605Smrg stub = stub_find_dynamic(funcName, 0); 138848b8605Smrg 139848b8605Smrg slot = (stub) ? stub_get_slot(stub) : -1; 140848b8605Smrg if (slot >= 0) { 141848b8605Smrg if (alias && stub_get_slot(alias) != slot) 142848b8605Smrg return -1; 143848b8605Smrg /* use the first existing stub as the alias */ 144848b8605Smrg if (!alias) 145848b8605Smrg alias = stub; 146848b8605Smrg 147848b8605Smrg function_stubs[i] = stub; 148848b8605Smrg } 149848b8605Smrg } 150848b8605Smrg 151848b8605Smrg /* generate missing stubs */ 152848b8605Smrg for (i = 0; function_names[i] != NULL && i < 8; i++) { 153848b8605Smrg const char * funcName = function_names[i] + 2; 154848b8605Smrg struct mapi_stub *stub; 155848b8605Smrg 156848b8605Smrg if (function_stubs[i]) 157848b8605Smrg continue; 158848b8605Smrg 159848b8605Smrg stub = stub_find_dynamic(funcName, 1); 160848b8605Smrg if (!stub) 161848b8605Smrg return -1; 162848b8605Smrg 163848b8605Smrg stub_fix_dynamic(stub, alias); 164848b8605Smrg if (!alias) 165848b8605Smrg alias = stub; 166848b8605Smrg } 167848b8605Smrg 168848b8605Smrg return (alias) ? stub_get_slot(alias) : -1; 169848b8605Smrg} 170848b8605Smrg 171848b8605Smrgstatic const struct mapi_stub * 172848b8605Smrg_glapi_get_stub(const char *name, int generate) 173848b8605Smrg{ 174848b8605Smrg const struct mapi_stub *stub; 175848b8605Smrg 176848b8605Smrg#ifdef USE_MGL_NAMESPACE 177848b8605Smrg if (name) 178848b8605Smrg name++; 179848b8605Smrg#endif 180848b8605Smrg 181848b8605Smrg if (!name || name[0] != 'g' || name[1] != 'l') 182848b8605Smrg return NULL; 183848b8605Smrg name += 2; 184848b8605Smrg 185848b8605Smrg stub = stub_find_public(name); 186848b8605Smrg if (!stub) 187848b8605Smrg stub = stub_find_dynamic(name, generate); 188848b8605Smrg 189848b8605Smrg return stub; 190848b8605Smrg} 191848b8605Smrg 192848b8605Smrg/** 193848b8605Smrg * Return offset of entrypoint for named function within dispatch table. 194848b8605Smrg */ 195848b8605Smrgint 196848b8605Smrg_glapi_get_proc_offset(const char *funcName) 197848b8605Smrg{ 198848b8605Smrg const struct mapi_stub *stub = _glapi_get_stub(funcName, 0); 199848b8605Smrg return (stub) ? stub_get_slot(stub) : -1; 200848b8605Smrg} 201848b8605Smrg 202848b8605Smrg/** 203848b8605Smrg * Return pointer to the named function. If the function name isn't found 204848b8605Smrg * in the name of static functions, try generating a new API entrypoint on 205848b8605Smrg * the fly with assembly language. 206848b8605Smrg */ 207848b8605Smrg_glapi_proc 208848b8605Smrg_glapi_get_proc_address(const char *funcName) 209848b8605Smrg{ 210848b8605Smrg const struct mapi_stub *stub = _glapi_get_stub(funcName, 1); 211848b8605Smrg return (stub) ? (_glapi_proc) stub_get_addr(stub) : NULL; 212848b8605Smrg} 213848b8605Smrg 214848b8605Smrg/** 215848b8605Smrg * Return the name of the function at the given dispatch offset. 216848b8605Smrg * This is only intended for debugging. 217848b8605Smrg */ 218848b8605Smrgconst char * 219848b8605Smrg_glapi_get_proc_name(unsigned int offset) 220848b8605Smrg{ 221848b8605Smrg const struct mapi_stub *stub = stub_find_by_slot(offset); 222848b8605Smrg return stub ? stub_get_name(stub) : NULL; 223848b8605Smrg} 224848b8605Smrg 225848b8605Smrg/** 226848b8605Smrg * This is a deprecated function which should not be used anymore. 227848b8605Smrg * It's only present to satisfy linking with older versions of libGL. 228848b8605Smrg */ 229848b8605Smrgunsigned long 230848b8605Smrg_glthread_GetID(void) 231848b8605Smrg{ 232848b8605Smrg return 0; 233848b8605Smrg} 234848b8605Smrg 235848b8605Smrgvoid 236848b8605Smrg_glapi_noop_enable_warnings(unsigned char enable) 237848b8605Smrg{ 238848b8605Smrg} 239848b8605Smrg 240848b8605Smrgvoid 241848b8605Smrg_glapi_set_warning_func(_glapi_proc func) 242848b8605Smrg{ 243848b8605Smrg} 244