/** * Fill-in the dispatch stub for the named function. * * This function is intended to be called by a hardware driver. When called, * a dispatch stub may be created created for the function. A pointer to this * dispatch function will be returned by glXGetProcAddress. * * \param function_names Array of pointers to function names that should * share a common dispatch offset. * \param parameter_signature String representing the types of the parameters * passed to the named function. Parameter types * are converted to characters using the following * rules: * - 'i' for \c GLint, \c GLuint, and \c GLenum * - 'p' for any pointer type * - 'f' for \c GLfloat and \c GLclampf * - 'd' for \c GLdouble and \c GLclampd * * \returns * The offset in the dispatch table of the named function. A pointer to the * driver's implementation of the named function should be stored at * \c dispatch_table[\c offset]. Return -1 if error/problem. * * \sa glXGetProcAddress * * \warning * This function can only handle up to 8 names at a time. As far as I know, * the maximum number of names ever associated with an existing GL function is * 4 (\c glPointParameterfSGIS, \c glPointParameterfEXT, * \c glPointParameterfARB, and \c glPointParameterf), so this should not be * too painful of a limitation. * * \todo * Check parameter_signature. */ int _glapi_add_dispatch( const char * const * function_names, const char * parameter_signature ) { const struct mapi_stub *function_stubs[8]; const struct mapi_stub *alias = NULL; unsigned i; (void) memset(function_stubs, 0, sizeof(function_stubs)); /* find the missing stubs, and decide the alias */ for (i = 0; function_names[i] != NULL && i < 8; i++) { const char * funcName = function_names[i]; const struct mapi_stub *stub; int slot; if (!funcName || funcName[0] != 'g' || funcName[1] != 'l') return -1; funcName += 2; stub = stub_find_public(funcName); if (!stub) stub = stub_find_dynamic(funcName, 0); slot = (stub) ? stub_get_slot(stub) : -1; if (slot >= 0) { if (alias && stub_get_slot(alias) != slot) return -1; /* use the first existing stub as the alias */ if (!alias) alias = stub; function_stubs[i] = stub; } } /* generate missing stubs */ for (i = 0; function_names[i] != NULL && i < 8; i++) { const char * funcName = function_names[i] + 2; struct mapi_stub *stub; if (function_stubs[i]) continue; stub = stub_find_dynamic(funcName, 1); if (!stub) return -1; stub_fix_dynamic(stub, alias); if (!alias) alias = stub; } return (alias) ? stub_get_slot(alias) : -1; }
static const struct mapi_stub * get_stub(const char *name, const struct mapi_stub *alias) { const struct mapi_stub *stub; stub = stub_find_public(name); if (!stub) { struct mapi_stub *dyn = stub_find_dynamic(name, 1); if (dyn) { stub_fix_dynamic(dyn, alias); stub = dyn; } } return stub; }