Loading the driver

Let's analyze the load_driver function, which is the one that finds and loads the OpenGL ES user space driver:

void *Loader::load_driver(const char* kind, 
egl_connection_t* cnx, uint32_t mask)
{
class MatchFile {
public:
static String8 find(const char* kind) {
...
};


String8 absolutePath = MatchFile::find(kind);
if (absolutePath.isEmpty()) {
// this happens often, we don't want to log an error
return 0;
}
const char* const driver_absolute_path = absolutePath.string();

void* dso = dlopen(driver_absolute_path, RTLD_NOW | RTLD_LOCAL);
if (dso == 0) {
const char* err = dlerror();
ALOGE("load_driver(%s): %s", driver_absolute_path, err?
err:"unknown");
return 0;
}

ALOGD("loaded %s", driver_absolute_path);

if (mask & EGL) {
getProcAddress = (getProcAddressType)dlsym(dso,
"eglGetProcAddress");

ALOGE_IF(!getProcAddress,
"can't find eglGetProcAddress() in %s",
driver_absolute_path);

egl_t* egl = &cnx->egl;
__eglMustCastToProperFunctionPointerType* curr =
(__eglMustCastToProperFunctionPointerType*)egl;
char const * const * api = egl_names;
while (*api) {
char const * name = *api;
__eglMustCastToProperFunctionPointerType f =
(__eglMustCastToProperFunctionPointerType)dlsym(dso,
name);
if (f == NULL) {
// couldn't find the entry-point, use
// eglGetProcAddress()

f = getProcAddress(name);
if (f == NULL) {
f = (__eglMustCastToProperFunctionPointerType)0;
}
}
*curr++ = f;
api++;
}
}

if (mask & GLESv1_CM) {
init_api(dso, gl_names,
(__eglMustCastToProperFunctionPointerType*)
&cnx->hooks[egl_connection_t::GLESv1_INDEX]->gl,
getProcAddress);
}

if (mask & GLESv2) {
init_api(dso, gl_names,
(__eglMustCastToProperFunctionPointerType*)
&cnx->hooks[egl_connection_t::GLESv2_INDEX]->gl,
getProcAddress);
}

return dso;
}

In the load_driver function, it defines a MatchFile inner class. It uses the MatchFile::find method to find the path of the libraries. The load_driver function has three parameters: kind, cnx, and mask. According to the kind of libraries, the parameter kind could be GLES, EGL, GLESv1_CM, or GLESv2. Once it gets the absolute path of a library, it calls the dlopen system function to open the shared library. The mask parameter is a bit map of the kind parameter. Using the mask parameter, it can initialize the cnx parameter according to the kind of library. As we mentioned before, the cnx parameter, which is an instance of egl_connection_t, has an egl field to store all the EGL function pointers. It has another field, hooks[GLESv1_INDEX]/ hooks[GLESv2_INDEX], to store all OpenGL ES functions.

If the library type is EGL, it gets the address of the eglGetProcAddress function by first calling the dlsym system function. After that, it will loop through all the function names defined in the egl_names global variable to find out the addresses and store them in cnx->egl. During the process, it tries to get the address using the dlsym system function first. If the call to dlsym fails, it will try it again using the eglGetProcAddress function.

If the library type is either GLESv1_CM or GLESv2, it calls another function, init_api, to initialize all OpenGL ES function pointers. In the init_api function, it will loop through all the function names defined in the gl_names global variable to find out the addresses and store them in cnx->hooks[egl_connection_t::GLESv?_INDEX]->gl.

Now we have done all the initialization of the OpenGL ES user space drivers and we can use the egl_connection_t data structure to access all OpenGL ES vendor APIs.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.19.223