/** * Return offset of entrypoint for named function within dispatch table. */ GLint _glapi_get_proc_offset(const char *funcName) { GLint offset; /* search extension functions first */ offset = get_extension_proc_offset(funcName); if (offset >= 0) return offset; /* search static functions */ return get_static_proc_offset(funcName); }
/** * Return offset of entrypoint for named function within dispatch table. */ PUBLIC GLint _glapi_get_proc_offset(const char *funcName) { /* search extension functions first */ GLuint i; for (i = 0; i < NumExtEntryPoints; i++) { if (strcmp(ExtEntryTable[i].name, funcName) == 0) { return ExtEntryTable[i].dispatch_offset; } } /* search static functions */ return get_static_proc_offset(funcName); }
PUBLIC int _glapi_add_dispatch(const char *const *function_names, const char *parameter_signature) { static int next_dynamic_offset = FIRST_DYNAMIC_OFFSET; const char *const real_sig = (parameter_signature != NULL) ? parameter_signature : ""; struct _glapi_function *entry[8]; GLboolean is_static[8]; unsigned i; unsigned j; int offset = ~0; int new_offset; (void) memset(is_static, 0, sizeof(is_static)); (void) memset(entry, 0, sizeof(entry)); for (i = 0; function_names[i] != NULL; i++) { /* Do some trivial validation on the name of the function. */ if (function_names[i][0] != 'g' || function_names[i][1] != 'l') return GL_FALSE; /* Determine if the named function already exists. If the function does * exist, it must have the same parameter signature as the function * being added. */ new_offset = get_static_proc_offset(function_names[i]); if (new_offset >= 0) { /* FIXME: Make sure the parameter signatures match! How do we get * FIXME: the parameter signature for static functions? */ if ((offset != ~0) && (new_offset != offset)) { return -1; } is_static[i] = GL_TRUE; offset = new_offset; } for (j = 0; j < NumExtEntryPoints; j++) { if (strcmp(ExtEntryTable[j].name, function_names[i]) == 0) { /* The offset may be ~0 if the function name was added by * glXGetProcAddress but never filled in by the driver. */ if (ExtEntryTable[j].dispatch_offset != ~0) { if (strcmp(real_sig, ExtEntryTable[j].parameter_signature) != 0) return -1; if ((offset != ~0) && (ExtEntryTable[j].dispatch_offset != offset)) { return -1; } offset = ExtEntryTable[j].dispatch_offset; } entry[i] = &ExtEntryTable[j]; break; } } } if (offset == ~0) { offset = next_dynamic_offset; next_dynamic_offset++; } for (i = 0; function_names[i] != NULL; i++) { if (!is_static[i]) { if (entry[i] == NULL) { entry[i] = add_function_name(function_names[i]); if (entry[i] == NULL) return -1; } entry[i]->parameter_signature = strdup(real_sig); entry[i]->dispatch_offset = offset; } } return offset; }
int _glapi_add_dispatch( const char * const * function_names, const char * parameter_signature ) { static int next_dynamic_offset = FIRST_DYNAMIC_OFFSET; const char * const real_sig = (parameter_signature != NULL) ? parameter_signature : ""; struct _glapi_function * entry[8]; GLboolean is_static[8]; unsigned i; int offset = ~0; init_glapi_relocs_once(); (void) memset( is_static, 0, sizeof( is_static ) ); (void) memset( entry, 0, sizeof( entry ) ); /* Find the _single_ dispatch offset for all function names that already * exist (and have a dispatch offset). */ for ( i = 0 ; function_names[i] != NULL ; i++ ) { const char * funcName = function_names[i]; int static_offset; int extension_offset; if (funcName[0] != 'g' || funcName[1] != 'l') return -1; /* search built-in functions */ static_offset = get_static_proc_offset(funcName); if (static_offset >= 0) { is_static[i] = GL_TRUE; /* FIXME: Make sure the parameter signatures match! How do we get * FIXME: the parameter signature for static functions? */ if ( (offset != ~0) && (static_offset != offset) ) { return -1; } offset = static_offset; continue; } /* search added extension functions */ entry[i] = get_extension_proc(funcName); if (entry[i] != NULL) { extension_offset = entry[i]->dispatch_offset; /* The offset may be ~0 if the function name was added by * glXGetProcAddress but never filled in by the driver. */ if (extension_offset == ~0) { continue; } if (strcmp(real_sig, entry[i]->parameter_signature) != 0) { return -1; } if ( (offset != ~0) && (extension_offset != offset) ) { return -1; } offset = extension_offset; } } /* If all function names are either new (or with no dispatch offset), * allocate a new dispatch offset. */ if (offset == ~0) { offset = next_dynamic_offset; next_dynamic_offset++; } /* Fill in the dispatch offset for the new function names (and those with * no dispatch offset). */ for ( i = 0 ; function_names[i] != NULL ; i++ ) { if (is_static[i]) { continue; } /* generate entrypoints for new function names */ if (entry[i] == NULL) { entry[i] = add_function_name( function_names[i] ); if (entry[i] == NULL) { /* FIXME: Possible memory leak here. */ return -1; } } if (entry[i]->dispatch_offset == ~0) { set_entry_info( entry[i], real_sig, offset ); } } return offset; }