/*! * This function queries each loaded vendor to determine if there is * a vendor-implemented dispatch function. The dispatch function * uses the vendor <-> API library ABI to determine the screen given * the parameters of the function and dispatch to the correct vendor's * implementation. */ __GLXextFuncPtr __glXGetGLXDispatchAddress(const GLubyte *procName) { __GLXextFuncPtr addr = NULL; __GLXvendorNameHash *pEntry, *tmp; /* * Note that if a GLX extension function doesn't depend on calling any * other GLX functions first, then the app could call it before loading any * vendor libraries. If that happens, then the entrypoint would go to a * no-op stub instead of the correct dispatch stub. * * Running into that case would be an application bug, since it means that * the application is calling an extension function without checking the * extension string -- calling glXGetClientString would have loaded the * vendor libraries for every screen. * * In order to work with a buggy app like that, we might have to find and * load all available vendor libraries until we find one that supports the * function. Lacking that, a user could work around the issue by setting * __GLX_VENDOR_LIBRARY_NAME. */ // Look through the vendors that we've already loaded, and see if any of // them support the function. LKDHASH_RDLOCK(__glXPthreadFuncs, __glXVendorNameHash); HASH_ITER(hh, _LH(__glXVendorNameHash), pEntry, tmp) { addr = __glXFindVendorDispatchAddress((const char *)procName, pEntry->vendor); if (addr) { break; } }
/* * This function queries each loaded vendor to determine if there is * a vendor-implemented dispatch function. The dispatch function * uses the vendor <-> API library ABI to determine the screen given * the parameters of the function and dispatch to the correct vendor's * implementation. */ __GLXextFuncPtr __glXGetGLXDispatchAddress(const GLubyte *procName) { __GLXextFuncPtr addr = NULL; __GLXvendorNameHash *pEntry, *tmp; /* * XXX for full correctness, we should probably load vendors * on all screens up-front before doing this. However, that * might be bad for performance? */ LKDHASH_RDLOCK(__glXPthreadFuncs, __glXVendorNameHash); HASH_ITER(hh, _LH(__glXVendorNameHash), pEntry, tmp) { // See if the current vendor supports this GLX entry point addr = pEntry->vendor->staticDispatch-> glxvc.getDispatchAddress(procName); if (addr) { // Allocate the new dispatch index. if (!AllocDispatchIndex(pEntry->vendor, procName)) { addr = NULL; } break; } }