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> 30b8e80941Smrg#include <stdlib.h> 31848b8605Smrg#include "glapi/glapi.h" 32848b8605Smrg#include "u_current.h" 33848b8605Smrg#include "table.h" /* for MAPI_TABLE_NUM_SLOTS */ 34848b8605Smrg#include "stub.h" 35848b8605Smrg 36848b8605Smrg/* 37848b8605Smrg * Global variables, _glapi_get_context, and _glapi_get_dispatch are defined in 38848b8605Smrg * u_current.c. 39848b8605Smrg */ 40848b8605Smrg 41848b8605Smrg#ifdef GLX_USE_TLS 42848b8605Smrg/* not used, but defined for compatibility */ 43848b8605Smrgconst struct _glapi_table *_glapi_Dispatch; 44848b8605Smrgconst void *_glapi_Context; 45848b8605Smrg#endif /* GLX_USE_TLS */ 46848b8605Smrg 47848b8605Smrgvoid 48848b8605Smrg_glapi_destroy_multithread(void) 49848b8605Smrg{ 50848b8605Smrg u_current_destroy(); 51848b8605Smrg} 52848b8605Smrg 53848b8605Smrgvoid 54848b8605Smrg_glapi_check_multithread(void) 55848b8605Smrg{ 56848b8605Smrg u_current_init(); 57848b8605Smrg} 58848b8605Smrg 59848b8605Smrgvoid 60848b8605Smrg_glapi_set_context(void *context) 61848b8605Smrg{ 62848b8605Smrg u_current_set_context((const void *) context); 63848b8605Smrg} 64848b8605Smrg 65848b8605Smrgvoid 66848b8605Smrg_glapi_set_dispatch(struct _glapi_table *dispatch) 67848b8605Smrg{ 68b8e80941Smrg u_current_set_table((const struct _glapi_table *) dispatch); 69848b8605Smrg} 70848b8605Smrg 71848b8605Smrg/** 72848b8605Smrg * Return size of dispatch table struct as number of functions (or 73848b8605Smrg * slots). 74848b8605Smrg */ 75848b8605Smrgunsigned int 76848b8605Smrg_glapi_get_dispatch_table_size(void) 77848b8605Smrg{ 78848b8605Smrg return MAPI_TABLE_NUM_SLOTS; 79848b8605Smrg} 80848b8605Smrg 81848b8605Smrg/** 82848b8605Smrg * Fill-in the dispatch stub for the named function. 83848b8605Smrg * 84848b8605Smrg * This function is intended to be called by a hardware driver. When called, 85848b8605Smrg * a dispatch stub may be created created for the function. A pointer to this 86848b8605Smrg * dispatch function will be returned by glXGetProcAddress. 87848b8605Smrg * 88848b8605Smrg * \param function_names Array of pointers to function names that should 89848b8605Smrg * share a common dispatch offset. 90848b8605Smrg * \param parameter_signature String representing the types of the parameters 91848b8605Smrg * passed to the named function. Parameter types 92848b8605Smrg * are converted to characters using the following 93848b8605Smrg * rules: 94848b8605Smrg * - 'i' for \c GLint, \c GLuint, and \c GLenum 95848b8605Smrg * - 'p' for any pointer type 96848b8605Smrg * - 'f' for \c GLfloat and \c GLclampf 97848b8605Smrg * - 'd' for \c GLdouble and \c GLclampd 98848b8605Smrg * 99848b8605Smrg * \returns 100848b8605Smrg * The offset in the dispatch table of the named function. A pointer to the 101848b8605Smrg * driver's implementation of the named function should be stored at 102848b8605Smrg * \c dispatch_table[\c offset]. Return -1 if error/problem. 103848b8605Smrg * 104848b8605Smrg * \sa glXGetProcAddress 105848b8605Smrg * 106848b8605Smrg * \warning 107848b8605Smrg * This function can only handle up to 8 names at a time. As far as I know, 108848b8605Smrg * the maximum number of names ever associated with an existing GL function is 109848b8605Smrg * 4 (\c glPointParameterfSGIS, \c glPointParameterfEXT, 110848b8605Smrg * \c glPointParameterfARB, and \c glPointParameterf), so this should not be 111848b8605Smrg * too painful of a limitation. 112848b8605Smrg * 113848b8605Smrg * \todo 114848b8605Smrg * Check parameter_signature. 115848b8605Smrg */ 116848b8605Smrgint 117848b8605Smrg_glapi_add_dispatch( const char * const * function_names, 118848b8605Smrg const char * parameter_signature ) 119848b8605Smrg{ 120848b8605Smrg const struct mapi_stub *function_stubs[8]; 121848b8605Smrg const struct mapi_stub *alias = NULL; 122848b8605Smrg unsigned i; 123848b8605Smrg 124848b8605Smrg (void) memset(function_stubs, 0, sizeof(function_stubs)); 125848b8605Smrg 126848b8605Smrg /* find the missing stubs, and decide the alias */ 127848b8605Smrg for (i = 0; function_names[i] != NULL && i < 8; i++) { 128848b8605Smrg const char * funcName = function_names[i]; 129848b8605Smrg const struct mapi_stub *stub; 130848b8605Smrg int slot; 131848b8605Smrg 132848b8605Smrg if (!funcName || funcName[0] != 'g' || funcName[1] != 'l') 133848b8605Smrg return -1; 134848b8605Smrg funcName += 2; 135848b8605Smrg 136848b8605Smrg stub = stub_find_public(funcName); 137848b8605Smrg if (!stub) 138848b8605Smrg stub = stub_find_dynamic(funcName, 0); 139848b8605Smrg 140848b8605Smrg slot = (stub) ? stub_get_slot(stub) : -1; 141848b8605Smrg if (slot >= 0) { 142848b8605Smrg if (alias && stub_get_slot(alias) != slot) 143848b8605Smrg return -1; 144848b8605Smrg /* use the first existing stub as the alias */ 145848b8605Smrg if (!alias) 146848b8605Smrg alias = stub; 147848b8605Smrg 148848b8605Smrg function_stubs[i] = stub; 149848b8605Smrg } 150848b8605Smrg } 151848b8605Smrg 152848b8605Smrg /* generate missing stubs */ 153848b8605Smrg for (i = 0; function_names[i] != NULL && i < 8; i++) { 154848b8605Smrg const char * funcName = function_names[i] + 2; 155848b8605Smrg struct mapi_stub *stub; 156848b8605Smrg 157848b8605Smrg if (function_stubs[i]) 158848b8605Smrg continue; 159848b8605Smrg 160848b8605Smrg stub = stub_find_dynamic(funcName, 1); 161848b8605Smrg if (!stub) 162848b8605Smrg return -1; 163848b8605Smrg 164848b8605Smrg stub_fix_dynamic(stub, alias); 165848b8605Smrg if (!alias) 166848b8605Smrg alias = stub; 167848b8605Smrg } 168848b8605Smrg 169848b8605Smrg return (alias) ? stub_get_slot(alias) : -1; 170848b8605Smrg} 171848b8605Smrg 172848b8605Smrgstatic const struct mapi_stub * 173848b8605Smrg_glapi_get_stub(const char *name, int generate) 174848b8605Smrg{ 175848b8605Smrg const struct mapi_stub *stub; 176848b8605Smrg 177848b8605Smrg#ifdef USE_MGL_NAMESPACE 178b8e80941Smrg if (name && name[0] == 'm') 179848b8605Smrg name++; 180848b8605Smrg#endif 181848b8605Smrg 182848b8605Smrg if (!name || name[0] != 'g' || name[1] != 'l') 183848b8605Smrg return NULL; 184848b8605Smrg name += 2; 185848b8605Smrg 186848b8605Smrg stub = stub_find_public(name); 187848b8605Smrg if (!stub) 188848b8605Smrg stub = stub_find_dynamic(name, generate); 189848b8605Smrg 190848b8605Smrg return stub; 191848b8605Smrg} 192848b8605Smrg 193848b8605Smrg/** 194848b8605Smrg * Return offset of entrypoint for named function within dispatch table. 195848b8605Smrg */ 196848b8605Smrgint 197848b8605Smrg_glapi_get_proc_offset(const char *funcName) 198848b8605Smrg{ 199848b8605Smrg const struct mapi_stub *stub = _glapi_get_stub(funcName, 0); 200848b8605Smrg return (stub) ? stub_get_slot(stub) : -1; 201848b8605Smrg} 202848b8605Smrg 203848b8605Smrg/** 204848b8605Smrg * Return pointer to the named function. If the function name isn't found 205848b8605Smrg * in the name of static functions, try generating a new API entrypoint on 206848b8605Smrg * the fly with assembly language. 207848b8605Smrg */ 208848b8605Smrg_glapi_proc 209848b8605Smrg_glapi_get_proc_address(const char *funcName) 210848b8605Smrg{ 211848b8605Smrg const struct mapi_stub *stub = _glapi_get_stub(funcName, 1); 212848b8605Smrg return (stub) ? (_glapi_proc) stub_get_addr(stub) : NULL; 213848b8605Smrg} 214848b8605Smrg 215848b8605Smrg/** 216848b8605Smrg * Return the name of the function at the given dispatch offset. 217848b8605Smrg * This is only intended for debugging. 218848b8605Smrg */ 219848b8605Smrgconst char * 220848b8605Smrg_glapi_get_proc_name(unsigned int offset) 221848b8605Smrg{ 222848b8605Smrg const struct mapi_stub *stub = stub_find_by_slot(offset); 223848b8605Smrg return stub ? stub_get_name(stub) : NULL; 224848b8605Smrg} 225848b8605Smrg 226b8e80941Smrg/** Return pointer to new dispatch table filled with no-op functions */ 227b8e80941Smrgstruct _glapi_table * 228b8e80941Smrg_glapi_new_nop_table(unsigned num_entries) 229b8e80941Smrg{ 230b8e80941Smrg struct _glapi_table *table; 231b8e80941Smrg 232b8e80941Smrg if (num_entries > MAPI_TABLE_NUM_SLOTS) 233b8e80941Smrg num_entries = MAPI_TABLE_NUM_SLOTS; 234b8e80941Smrg 235b8e80941Smrg table = malloc(num_entries * sizeof(mapi_func)); 236b8e80941Smrg if (table) { 237b8e80941Smrg memcpy(table, table_noop_array, num_entries * sizeof(mapi_func)); 238b8e80941Smrg } 239b8e80941Smrg return table; 240b8e80941Smrg} 241b8e80941Smrg 242b8e80941Smrgvoid 243b8e80941Smrg_glapi_set_nop_handler(_glapi_nop_handler_proc func) 244b8e80941Smrg{ 245b8e80941Smrg table_set_noop_handler(func); 246b8e80941Smrg} 247b8e80941Smrg 248848b8605Smrg/** 249848b8605Smrg * This is a deprecated function which should not be used anymore. 250848b8605Smrg * It's only present to satisfy linking with older versions of libGL. 251848b8605Smrg */ 252848b8605Smrgunsigned long 253848b8605Smrg_glthread_GetID(void) 254848b8605Smrg{ 255848b8605Smrg return 0; 256848b8605Smrg} 257848b8605Smrg 258848b8605Smrgvoid 259848b8605Smrg_glapi_noop_enable_warnings(unsigned char enable) 260848b8605Smrg{ 261848b8605Smrg} 262848b8605Smrg 263848b8605Smrgvoid 264848b8605Smrg_glapi_set_warning_func(_glapi_proc func) 265848b8605Smrg{ 266848b8605Smrg} 267