EGL: Rework the current rendering API.

libEGL will now forward calls to eglBindAPI to the vendor libraries.

Defined as part of the interface that libEGL only supports OpenGL and GLES.

This should simplify the task of porting a driver to EGL, since the eglBindAPI
behavior is closer to a non-glvnd driver.
This commit is contained in:
Kyle Brenneman 2016-07-05 14:41:50 -06:00
parent 31c5e7f602
commit f42d89dd99
4 changed files with 25 additions and 38 deletions

View file

@ -61,17 +61,17 @@ extern "C" {
/*
* Rendering API handling:
*
* libEGL currently only supports OpenGL and OpenGL ES, but not OpenVG.
* libEGL only supports OpenGL and OpenGL ES, not OpenVG. If OpenVG or any
* other API is added, then the major version number will be incremented.
*
* libEGL itself will keep track of the current rendering API. Vendor libraries
* must query the current API from libEGL using the getCurrentApi callback.
* When the application calls eglBindAPI, libEGL will forward the call to every
* vendor library. In addition, a vendor library can query the current API from
* libEGL using the getCurrentApi callback.
*
* EGL functions are dispatched to vendor libraries regardless of the current
* API. If a vendor does not support the current API, then it must return an
* appropriate error code.
*
* libEGL does not call into the vendor library when the current API changes.
* As such, the vendor's implementation of eglBindAPI is never called.
* Vendor libraries are not required to support both GL and GLES, but they must
* be able to deal with either one as the current rendering API. If a vendor
* doesn't support the current API, then it should return an error from
* eglCreateContext.
*/
/*!
@ -271,30 +271,13 @@ typedef struct __EGLapiImportsRec {
*/
/*!
* This retrieves the pointer to the real EGL function.
* This retrieves the pointer to the real EGL or core GL function.
*
* \param procName The name of the function.
* \return A pointer to a function, or \c NULL if the vendor does not
* support the function.
*/
__eglMustCastToProperFunctionPointerType (* getEGLProcAddress) (const char *procName);
/*!
* Returns a pointer to a client API (OpenGL or OpenVG) function.
*
* The vendor library must return NULL if \c procName is an EGL function,
* or if it doesn't match \p api. libEGL will use the result of this
* function to determine which client API a function belongs to.
*
* Also note that \p api will be EGL_OPENGL_API for OpenGL and OpenGLES
* functions.
*
* \param api The API to look up.
* \param procName The name of the function.
* \return A pointer to a function, or \c NULL if the vendor does not
* support the function.
*/
__eglMustCastToProperFunctionPointerType (* getClientApiProcAddress) (EGLint api, const char *procName);
__eglMustCastToProperFunctionPointerType (* getProcAddress) (const char *procName);
/*!
* This retrieves vendor-neutral functions which use the
@ -310,7 +293,7 @@ typedef struct __EGLapiImportsRec {
* \return A pointer to a function, or \c NULL if the vendor does not
* support the function or \p procName is not a EGL display function.
*/
__eglMustCastToProperFunctionPointerType (*getEGLDispatchAddress) (const char *procName);
__eglMustCastToProperFunctionPointerType (*getDispatchAddress) (const char *procName);
/*!
* This notifies the vendor library which dispatch table index is

View file

@ -358,6 +358,11 @@ PUBLIC EGLBoolean EGLAPIENTRY eglBindAPI(EGLenum api)
return EGL_FALSE;
}
state->currentClientApi = api;
glvnd_list_for_each_entry(vendor, vendorList, entry) {
if (vendor->staticDispatch.bindAPI != NULL) {
vendor->staticDispatch.bindAPI(api);
}
}
return EGL_TRUE;
}

View file

@ -77,7 +77,7 @@ __eglMustCastToProperFunctionPointerType __eglGetEGLDispatchAddress(const char *
// Check each vendor library for a dispatch stub.
glvnd_list_for_each_entry(vendor, vendorList, entry) {
addr = vendor->eglvc.getEGLDispatchAddress(procName);
addr = vendor->eglvc.getDispatchAddress(procName);
if (addr != NULL) {
break;
}
@ -122,7 +122,7 @@ __eglMustCastToProperFunctionPointerType __eglFetchDispatchEntry(
}
// Get the real address.
addr = vendor->eglvc.getEGLProcAddress(procName);
addr = vendor->eglvc.getProcAddress(procName);
if (addr != NULL) {
// Record the address in the vendor's hashtable. Note that if this
// fails, it's not fatal. It just means we'll have to call

View file

@ -191,7 +191,7 @@ static GLboolean LookupVendorEntrypoints(__EGLvendorInfo *vendor)
#define LOADENTRYPOINT(ptr, name) do { \
*((__eglMustCastToProperFunctionPointerType *) &vendor->staticDispatch.ptr) = \
vendor->eglvc.getEGLProcAddress(name); \
vendor->eglvc.getProcAddress(name); \
if (vendor->staticDispatch.ptr == NULL) { return GL_FALSE; } \
} while(0)
@ -218,7 +218,6 @@ static GLboolean LookupVendorEntrypoints(__EGLvendorInfo *vendor)
LOADENTRYPOINT(releaseTexImage, "eglReleaseTexImage" );
LOADENTRYPOINT(surfaceAttrib, "eglSurfaceAttrib" );
LOADENTRYPOINT(swapInterval, "eglSwapInterval" );
LOADENTRYPOINT(bindAPI, "eglBindAPI" );
LOADENTRYPOINT(createPbufferFromClientBuffer, "eglCreatePbufferFromClientBuffer" );
LOADENTRYPOINT(releaseThread, "eglReleaseThread" );
LOADENTRYPOINT(waitClient, "eglWaitClient" );
@ -228,7 +227,8 @@ static GLboolean LookupVendorEntrypoints(__EGLvendorInfo *vendor)
// The remaining functions here are optional.
#define LOADENTRYPOINT(ptr, name) \
*((__eglMustCastToProperFunctionPointerType *) &vendor->staticDispatch.ptr) = \
vendor->eglvc.getEGLProcAddress(name);
vendor->eglvc.getProcAddress(name);
LOADENTRYPOINT(bindAPI, "eglBindAPI" );
LOADENTRYPOINT(createSync, "eglCreateSync" );
LOADENTRYPOINT(destroySync, "eglDestroySync" );
LOADENTRYPOINT(clientWaitSync, "eglClientWaitSync" );
@ -251,7 +251,7 @@ static GLboolean LookupVendorEntrypoints(__EGLvendorInfo *vendor)
static void *VendorGetProcAddressCallback(const char *procName, void *param)
{
__EGLvendorInfo *vendor = (__EGLvendorInfo *) param;
return vendor->eglvc.getClientApiProcAddress(EGL_OPENGL_API, procName);
return vendor->eglvc.getProcAddress(procName);
}
static __EGLvendorInfo *LoadVendorFromConfigFile(const char *filename)
@ -372,9 +372,8 @@ static __EGLvendorInfo *LoadVendor(const char *filename)
// Make sure all the required functions are there.
if (vendor->eglvc.getPlatformDisplay == NULL
|| vendor->eglvc.getSupportsAPI == NULL
|| vendor->eglvc.getEGLProcAddress == NULL
|| vendor->eglvc.getClientApiProcAddress == NULL
|| vendor->eglvc.getEGLDispatchAddress == NULL
|| vendor->eglvc.getProcAddress == NULL
|| vendor->eglvc.getDispatchAddress == NULL
|| vendor->eglvc.setDispatchIndex == NULL) {
goto fail;
}