/*1* Mesa 3-D graphics library2*3* Copyright (C) 1999-2008 Brian Paul All Rights Reserved.4* Copyright (C) 2010 LunarG Inc.5*6* Permission is hereby granted, free of charge, to any person obtaining a7* copy of this software and associated documentation files (the "Software"),8* to deal in the Software without restriction, including without limitation9* the rights to use, copy, modify, merge, publish, distribute, sublicense,10* and/or sell copies of the Software, and to permit persons to whom the11* Software is furnished to do so, subject to the following conditions:12*13* The above copyright notice and this permission notice shall be included14* in all copies or substantial portions of the Software.15*16* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR17* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,18* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL19* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER20* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING21* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER22* DEALINGS IN THE SOFTWARE.23*24* Authors:25* Chia-I Wu <[email protected]>26*/2728#include <string.h>29#include <stdlib.h>30#include "glapi/glapi.h"31#include "u_current.h"32#include "table.h" /* for MAPI_TABLE_NUM_SLOTS */33#include "stub.h"3435/*36* Global variables, _glapi_get_context, and _glapi_get_dispatch are defined in37* u_current.c.38*/3940#ifdef USE_ELF_TLS41/* not used, but defined for compatibility */42const struct _glapi_table *_glapi_Dispatch;43const void *_glapi_Context;44#endif /* USE_ELF_TLS */4546void47_glapi_destroy_multithread(void)48{49u_current_destroy();50}5152void53_glapi_check_multithread(void)54{55u_current_init();56}5758void59_glapi_set_context(void *context)60{61u_current_set_context((const void *) context);62}6364void65_glapi_set_dispatch(struct _glapi_table *dispatch)66{67u_current_set_table((const struct _glapi_table *) dispatch);68}6970/**71* Return size of dispatch table struct as number of functions (or72* slots).73*/74unsigned int75_glapi_get_dispatch_table_size(void)76{77return MAPI_TABLE_NUM_SLOTS;78}7980/**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 this85* dispatch function will be returned by glXGetProcAddress.86*87* \param function_names Array of pointers to function names that should88* share a common dispatch offset.89* \param parameter_signature String representing the types of the parameters90* passed to the named function. Parameter types91* are converted to characters using the following92* rules:93* - 'i' for \c GLint, \c GLuint, and \c GLenum94* - 'p' for any pointer type95* - 'f' for \c GLfloat and \c GLclampf96* - 'd' for \c GLdouble and \c GLclampd97*98* \returns99* The offset in the dispatch table of the named function. A pointer to the100* driver's implementation of the named function should be stored at101* \c dispatch_table[\c offset]. Return -1 if error/problem.102*103* \sa glXGetProcAddress104*105* \warning106* 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 is108* 4 (\c glPointParameterfSGIS, \c glPointParameterfEXT,109* \c glPointParameterfARB, and \c glPointParameterf), so this should not be110* too painful of a limitation.111*112* \todo113* Check parameter_signature.114*/115int116_glapi_add_dispatch( const char * const * function_names,117const char * parameter_signature )118{119const struct mapi_stub *function_stubs[8];120const struct mapi_stub *alias = NULL;121unsigned i;122123(void) memset(function_stubs, 0, sizeof(function_stubs));124125/* find the missing stubs, and decide the alias */126for (i = 0; function_names[i] != NULL && i < 8; i++) {127const char * funcName = function_names[i];128const struct mapi_stub *stub;129int slot;130131if (!funcName || funcName[0] != 'g' || funcName[1] != 'l')132return -1;133funcName += 2;134135stub = stub_find_public(funcName);136if (!stub)137stub = stub_find_dynamic(funcName, 0);138139slot = (stub) ? stub_get_slot(stub) : -1;140if (slot >= 0) {141if (alias && stub_get_slot(alias) != slot)142return -1;143/* use the first existing stub as the alias */144if (!alias)145alias = stub;146147function_stubs[i] = stub;148}149}150151/* generate missing stubs */152for (i = 0; function_names[i] != NULL && i < 8; i++) {153const char * funcName = function_names[i] + 2;154struct mapi_stub *stub;155156if (function_stubs[i])157continue;158159stub = stub_find_dynamic(funcName, 1);160if (!stub)161return -1;162163stub_fix_dynamic(stub, alias);164if (!alias)165alias = stub;166}167168return (alias) ? stub_get_slot(alias) : -1;169}170171#if defined(ANDROID) && ANDROID_API_LEVEL <= 30172static int is_debug_marker_func(const char *name)173{174return (!strcmp(name, "InsertEventMarkerEXT") ||175!strcmp(name, "PushGroupMarkerEXT") ||176!strcmp(name, "PopGroupMarkerEXT"));177}178#endif179180static const struct mapi_stub *181_glapi_get_stub(const char *name, int generate)182{183const struct mapi_stub *stub;184185if (!name || name[0] != 'g' || name[1] != 'l')186return NULL;187name += 2;188189stub = stub_find_public(name);190#if defined(ANDROID) && ANDROID_API_LEVEL <= 30191/* Android framework till API Level 30 uses function pointers from192* eglGetProcAddress without checking GL_EXT_debug_marker.193* Make sure we don't return stub function pointers if we don't194* support GL_EXT_debug_marker */195if (!stub && !is_debug_marker_func(name))196#else197if (!stub)198#endif199stub = stub_find_dynamic(name, generate);200201return stub;202}203204/**205* Return offset of entrypoint for named function within dispatch table.206*/207int208_glapi_get_proc_offset(const char *funcName)209{210const struct mapi_stub *stub = _glapi_get_stub(funcName, 0);211return (stub) ? stub_get_slot(stub) : -1;212}213214/**215* Return pointer to the named function. If the function name isn't found216* in the name of static functions, try generating a new API entrypoint on217* the fly with assembly language.218*/219_glapi_proc220_glapi_get_proc_address(const char *funcName)221{222const struct mapi_stub *stub = _glapi_get_stub(funcName, 1);223return (stub) ? (_glapi_proc) stub_get_addr(stub) : NULL;224}225226/**227* Return the name of the function at the given dispatch offset.228* This is only intended for debugging.229*/230const char *231_glapi_get_proc_name(unsigned int offset)232{233const struct mapi_stub *stub = stub_find_by_slot(offset);234return stub ? stub_get_name(stub) : NULL;235}236237/** Return pointer to new dispatch table filled with no-op functions */238struct _glapi_table *239_glapi_new_nop_table(unsigned num_entries)240{241struct _glapi_table *table;242243if (num_entries > MAPI_TABLE_NUM_SLOTS)244num_entries = MAPI_TABLE_NUM_SLOTS;245246table = malloc(num_entries * sizeof(mapi_func));247if (table) {248memcpy(table, table_noop_array, num_entries * sizeof(mapi_func));249}250return table;251}252253void254_glapi_set_nop_handler(_glapi_nop_handler_proc func)255{256table_set_noop_handler(func);257}258259/**260* This is a deprecated function which should not be used anymore.261* It's only present to satisfy linking with older versions of libGL.262*/263unsigned long264_glthread_GetID(void)265{266return 0;267}268269void270_glapi_noop_enable_warnings(unsigned char enable)271{272}273274void275_glapi_set_warning_func(_glapi_proc func)276{277}278279280