Register vendors with GLdispatch

This implements the notion of a "vendor ID" that is unique to each
vendor library instance loaded in a process.  When entrypoint rewriting
is implemented, this will be used by libglvnd to determine whether a
given entrypoint implementation is compatible with a given context, by
comparing the vendor owning the context with the vendor owning the
implementation.

This changes the function prototype of __glDispatchMakeCurrent()
to include the vendorID as an argument, which will be saved off in the
API state, and return a boolean value to indicate whether make current
succeeded.
This commit is contained in:
Brian Nguyen 2014-01-23 19:51:49 -08:00 committed by brnguyen
parent ac9d409294
commit a033f25bf0
6 changed files with 74 additions and 15 deletions

View file

@ -232,6 +232,8 @@ static __GLXAPIState *CreateAPIState(glvnd_thread_t tid)
apiState->glas.tag = GLDISPATCH_API_GLX;
apiState->glas.id = malloc(sizeof(glvnd_thread_t));
apiState->glas.vendorID = -1;
*((glvnd_thread_t *)apiState->glas.id) = tid;
HASH_ADD_KEYPTR(hh, _LH(__glXAPIStateHash), apiState->glas.id,
@ -471,6 +473,8 @@ static Bool MakeContextCurrentInternal(Display *dpy,
return True;
} else {
assert(newVendor);
/* Update the current display and drawable(s) in this apiState */
apiState->currentDisplay = dpy;
apiState->currentDraw = draw;
@ -498,12 +502,14 @@ static Bool MakeContextCurrentInternal(Display *dpy,
* Call into GLdispatch to set up the current context and
* GL dispatch table.
*/
__glDispatchMakeCurrent(&apiState->glas,
newVendor->glDispatch,
(void *)context);
}
ret = __glDispatchMakeCurrent(
&apiState->glas,
newVendor->glDispatch,
(void *)context,
newVendor->vendorID);
return True;
return ret;
}
}
static void SaveCurrentValues(GLXDrawable *pDraw,

View file

@ -316,10 +316,11 @@ typedef struct __GLXapiImportsRec {
#define __GLX_MAIN_PROTO(version, exports, vendorName) \
const __GLXapiImports *__glx_Main(uint32_t version, \
const __GLXapiExports *exports, \
const char *vendorName)
const char *vendorName, \
int vendorID)
typedef const __GLXapiImports *(*__PFNGLXMAINPROC)
(uint32_t, const __GLXapiExports *, const char*);
(uint32_t, const __GLXapiExports *, const char *, int);
/*!
* @}

View file

@ -302,6 +302,7 @@ __GLXvendorInfo *__glXLookupVendorByName(const char *vendorName)
__GLXdispatchTableDynamic *dynDispatch;
__GLXvendorInfo *vendor = NULL;
Bool locked = False;
int vendorID = -1;
LKDHASH_RDLOCK(__glXPthreadFuncs, __glXVendorNameHash);
HASH_FIND(hh, _LH(__glXVendorNameHash), vendorName, strlen(vendorName), pEntry);
@ -340,9 +341,13 @@ __GLXvendorInfo *__glXLookupVendorByName(const char *vendorName)
__glXPthreadFuncs.once(&glxExportsTableOnceControl,
InitExportsTable);
vendorID = __glDispatchNewVendorID();
assert(vendorID >= 0);
dispatch = (*glxMainProc)(GLX_VENDOR_ABI_VERSION,
&glxExportsTable,
vendorName);
vendorName,
vendorID);
if (!dispatch) {
goto fail;
}
@ -354,6 +359,8 @@ __GLXvendorInfo *__glXLookupVendorByName(const char *vendorName)
}
pEntry->name = vendor->name = strdup(vendorName);
vendor->vendorID = vendorID;
if (!vendor->name) {
goto fail;
}

View file

@ -37,6 +37,7 @@
* Structure containing relevant per-vendor information.
*/
typedef struct __GLXvendorInfoRec {
int vendorID; //< unique GLdispatch ID
char *name; //< name of the vendor
void *dlhandle; //< shared library handle
const __GLXdispatchTableStatic *staticDispatch; //< static GLX dispatch table

View file

@ -94,6 +94,12 @@ static struct glvnd_list extProcList;
*/
static int latestGeneration;
/*
* Used when generating new vendor IDs for GLdispatch clients. Valid vendor
* IDs must be non-zero.
*/
static int firstUnusedVendorID = 1;
/*
* The dispatch lock. This should be taken around any code that manipulates the
* above global variables or makes calls to _glapi_add_dispatch() or
@ -146,6 +152,16 @@ void __glDispatchInit(GLVNDPthreadFuncs *funcs)
}
}
int __glDispatchNewVendorID(void)
{
int vendorID;
LockDispatch();
vendorID = firstUnusedVendorID++;
UnlockDispatch();
return vendorID;
}
static void noop_func(void)
{
@ -377,9 +393,10 @@ static struct _glapi_table
return table;
}
PUBLIC void __glDispatchMakeCurrent(__GLdispatchAPIState *apiState,
__GLdispatchTable *dispatch,
void *context)
PUBLIC GLboolean __glDispatchMakeCurrent(__GLdispatchAPIState *apiState,
__GLdispatchTable *dispatch,
void *context,
int vendorID)
{
__GLdispatchAPIState *curApiState = (__GLdispatchAPIState *)
_glapi_get_current(CURRENT_API_STATE);
@ -417,6 +434,7 @@ PUBLIC void __glDispatchMakeCurrent(__GLdispatchAPIState *apiState,
*/
apiState->context = context;
apiState->dispatch = dispatch;
apiState->vendorID = vendorID;
/*
* Set the current state in TLS.
@ -424,6 +442,8 @@ PUBLIC void __glDispatchMakeCurrent(__GLdispatchAPIState *apiState,
_glapi_set_current(context, CURRENT_CONTEXT);
_glapi_set_current(apiState, CURRENT_API_STATE);
_glapi_set_dispatch(dispatch->table);
return GL_TRUE;
}
PUBLIC void __glDispatchLoseCurrent(void)
@ -438,6 +458,7 @@ PUBLIC void __glDispatchLoseCurrent(void)
curApiState->dispatch = NULL;
curApiState->context = NULL;
curApiState->vendorID = -1;
}
LockDispatch();

View file

@ -71,6 +71,10 @@ enum {
* a context current). This is done to conserve TLS space.
*/
typedef struct __GLdispatchAPIStateRec {
/*************************************************************************
* Winsys-managed variables: fixed for lifetime of state
*************************************************************************/
/*!
* Namespace of the state: either API_GLX or API_EGL
*/
@ -82,6 +86,15 @@ typedef struct __GLdispatchAPIStateRec {
*/
void *id;
/*************************************************************************
* GLdispatch-managed variables: Modified by MakeCurrent()
*************************************************************************/
/*!
* ID of the current vendor for this state
*/
int vendorID;
/*!
* The current (high-level) __GLdispatch table
*/
@ -98,6 +111,12 @@ typedef struct __GLdispatchAPIStateRec {
*/
PUBLIC void __glDispatchInit(GLVNDPthreadFuncs *funcs);
/*!
* This returns a process-unique ID that is suitable for use with a new GL
* vendor.
*/
PUBLIC int __glDispatchNewVendorID(void);
/*!
* Get a dispatch stub suitable for returning to the application from
* GetProcAddress().
@ -128,11 +147,15 @@ PUBLIC void __glDispatchDestroyTable(__GLdispatchTable *dispatch);
/*!
* This makes the given API state current, and assigns this API state
* the passed-in current dispatch table and context.
* the passed-in current dispatch table, context, and vendor ID.
*
* This returns GL_FALSE if the make current operation failed, and GL_TRUE
* if it succeeded.
*/
PUBLIC void __glDispatchMakeCurrent(__GLdispatchAPIState *apiState,
__GLdispatchTable *dispatch,
void *context);
PUBLIC GLboolean __glDispatchMakeCurrent(__GLdispatchAPIState *apiState,
__GLdispatchTable *dispatch,
void *context,
int vendorID);
/*!
* This makes the NOP dispatch table current and sets the current context and