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:
parent
ac9d409294
commit
a033f25bf0
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
||||
/*!
|
||||
* @}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue