GLX: Assign indices to the GLX dispatch functions defined in libGLX.
The dispatch functions in libGLX are now added to the GLX dispatch list just like vendor-provided dispatch functions would be. The function name cache in glXGetProcAddress is no longer required for correctness, because it can look up a locally-defined dispatch stub in the same list as the vendor-provided stubs. In addition to simplifying glXGetProcAddress, this allows vendor libraries to look up all GLX functions by index. In particular, this would allow a vendor to look up glXDestroyContext, which would let it recover properly if it fails to add a new context to the context-to-vendor mapping.
This commit is contained in:
parent
8167e35e53
commit
774c9b25cb
|
@ -1658,29 +1658,10 @@ PUBLIC void glXSelectEvent(Display *dpy, GLXDrawable draw, unsigned long event_m
|
|||
}
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
GLubyte *procName;
|
||||
__GLXextFuncPtr addr;
|
||||
UT_hash_handle hh;
|
||||
} __GLXprocAddressHash;
|
||||
|
||||
static DEFINE_INITIALIZED_LKDHASH(__GLXprocAddressHash, __glXProcAddressHash);
|
||||
|
||||
#define LOCAL_FUNC_TABLE_ENTRY(func) \
|
||||
{ (GLubyte *)#func, (__GLXextFuncPtr)(func) },
|
||||
|
||||
/*
|
||||
* This helper function initializes the __GLXprocAddressHash with the
|
||||
* dispatch functions implemented above.
|
||||
*/
|
||||
void cacheInitializeOnce(void)
|
||||
const __GLXlocalDispatchFunction LOCAL_GLX_DISPATCH_FUNCTIONS[] =
|
||||
{
|
||||
size_t i;
|
||||
__GLXprocAddressHash *pEntry;
|
||||
const struct {
|
||||
const GLubyte *procName;
|
||||
__GLXextFuncPtr addr;
|
||||
} localFuncTable[] = {
|
||||
#define LOCAL_FUNC_TABLE_ENTRY(func) \
|
||||
{ #func, (__GLXextFuncPtr)(func) },
|
||||
LOCAL_FUNC_TABLE_ENTRY(glXChooseFBConfig)
|
||||
LOCAL_FUNC_TABLE_ENTRY(glXChooseVisual)
|
||||
LOCAL_FUNC_TABLE_ENTRY(glXCopyContext)
|
||||
|
@ -1724,27 +1705,17 @@ void cacheInitializeOnce(void)
|
|||
|
||||
LOCAL_FUNC_TABLE_ENTRY(glXImportContextEXT)
|
||||
LOCAL_FUNC_TABLE_ENTRY(glXFreeContextEXT)
|
||||
};
|
||||
#undef LOCAL_FUNC_TABLE_ENTRY
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
LKDHASH_WRLOCK(__glXProcAddressHash);
|
||||
typedef struct {
|
||||
GLubyte *procName;
|
||||
__GLXextFuncPtr addr;
|
||||
UT_hash_handle hh;
|
||||
} __GLXprocAddressHash;
|
||||
|
||||
// Initialize the hash table with our locally-exported functions
|
||||
|
||||
for (i = 0; i < ARRAY_LEN(localFuncTable); i++) {
|
||||
pEntry = malloc(sizeof(*pEntry));
|
||||
if (!pEntry) {
|
||||
assert(pEntry);
|
||||
break;
|
||||
}
|
||||
pEntry->procName =
|
||||
(GLubyte *)strdup((const char *)localFuncTable[i].procName);
|
||||
pEntry->addr = localFuncTable[i].addr;
|
||||
HASH_ADD_KEYPTR(hh, _LH(__glXProcAddressHash), pEntry->procName,
|
||||
strlen((const char *)pEntry->procName), pEntry);
|
||||
}
|
||||
LKDHASH_UNLOCK(__glXProcAddressHash);
|
||||
|
||||
}
|
||||
static DEFINE_INITIALIZED_LKDHASH(__GLXprocAddressHash, __glXProcAddressHash);
|
||||
|
||||
static void CleanupProcAddressEntry(void *unused, __GLXprocAddressHash *pEntry)
|
||||
{
|
||||
|
@ -1761,11 +1732,8 @@ static __GLXextFuncPtr __glXGetCachedProcAddress(const GLubyte *procName)
|
|||
* If this is the first time GetProcAddress has been called,
|
||||
* initialize the hash table with locally-exported functions.
|
||||
*/
|
||||
static glvnd_once_t cacheInitializeOnceControl = GLVND_ONCE_INIT;
|
||||
__GLXprocAddressHash *pEntry = NULL;
|
||||
|
||||
__glvndPthreadFuncs.once(&cacheInitializeOnceControl, cacheInitializeOnce);
|
||||
|
||||
LKDHASH_RDLOCK(__glXProcAddressHash);
|
||||
HASH_FIND(hh, _LH(__glXProcAddressHash), procName,
|
||||
strlen((const char *)procName), pEntry);
|
||||
|
|
|
@ -1040,7 +1040,17 @@ __GLXvendorInfo *__glXVendorFromDrawable(Display *dpy, GLXDrawable drawable)
|
|||
|
||||
void __glXMappingInit(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
__glvndWinsysDispatchInit();
|
||||
|
||||
// Add all of the GLX dispatch stubs that are defined in libGLX itself.
|
||||
for (i=0; LOCAL_GLX_DISPATCH_FUNCTIONS[i].name != NULL; i++) {
|
||||
// TODO: Is there any way to recover from a malloc failure here?
|
||||
__glvndWinsysDispatchAllocIndex(
|
||||
LOCAL_GLX_DISPATCH_FUNCTIONS[i].name,
|
||||
LOCAL_GLX_DISPATCH_FUNCTIONS[i].addr);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
|
@ -84,6 +84,17 @@ typedef struct __GLXdisplayInfoRec {
|
|||
Bool libglvndExtensionSupported;
|
||||
} __GLXdisplayInfo;
|
||||
|
||||
typedef struct __GLXlocalDispatchFunctionRec {
|
||||
const char *name;
|
||||
__GLXextFuncPtr addr;
|
||||
} __GLXlocalDispatchFunction;
|
||||
|
||||
/*!
|
||||
* A NULL-termianted list of GLX dispatch functions that are implemented in
|
||||
* libGLX instead of in any vendor library.
|
||||
*/
|
||||
extern const __GLXlocalDispatchFunction LOCAL_GLX_DISPATCH_FUNCTIONS[];
|
||||
|
||||
/*!
|
||||
* Accessor functions used to retrieve the "current" dispatch table for each of
|
||||
* the three types of dispatch tables (see libglxabi.h for an explanation of
|
||||
|
|
Loading…
Reference in a new issue