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:
Kyle Brenneman 2016-05-03 14:12:05 -06:00
parent 8167e35e53
commit 774c9b25cb
3 changed files with 33 additions and 44 deletions

View file

@ -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);

View file

@ -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);
}
}
/*!

View file

@ -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