EGL/目录生成libEGL.so
eglApi.cpp eglGetDisplay()触发loader加载libEGL_xxx.so,libGLESv1_CM_xxx.so,libGLESv2_xxx.so
或者libGLES_android.so,从中取出EGL和GLES函数的地址,注册到
struct egl_connection_t
{
inline egl_connection_t() : dso(0) { }
void * dso;
gl_hooks_t * hooks[2];//gles函数指针数组 v1和v2
EGLint major;
EGLint minor;
egl_t egl;//egl函数指针数组
};
有两个egl_connection_t
gEGLImpl[IMPL_SOFTWARE]
gEGLImpl[IMPL_HARDWARE]
应用调用Egl函数调用libEGL.so中的eglApi.cpp中的函数,进而调用到egl_connection_t:egl中注册的函数。
GLES_CM/目录生成libGLESv1_CM.so
GLES2/目录生成libGLESv2.so
应用调用GLES相关的api对调用到libGLESv1_CM.so/libGLESv2.so中的函数,gl.cpp/gl2.cpp中会根据threadprivate
变量找到对应的egl_connection_t,从而查找到hooks中注册的函数。
----------------------------------------
libEGL.so,libGLESv1_CM.so,libGLESv2.so是opengl对外的接口。
libGLESv1_CM.so,libGLESv2.so是绘制api,其通过查找hook表调用相应的程序,这个表通过libEGL.so是适配层,应用调用egl的api,初始化一个session,libEGL.so可以根据client的请求参数和egl.cfg配置文件,打开相应的动态库(软件的或者硬件的),从中获得相应api的指针,初始化hook数组。
status_t EGLUtils::selectConfigForPixelFormat(
EGLDisplay dpy,
EGLint const* attrs,
PixelFormat format,
EGLConfig* outConfig)
{
EGLint numConfigs = -1, n=0;
if (!attrs)
return BAD_VALUE;
if (outConfig == NULL)
return BAD_VALUE;
// Get all the "potential match" configs...
if (eglGetConfigs(dpy, NULL, 0, &numConfigs) == EGL_FALSE)
return BAD_VALUE;
EGLConfig* const configs = (EGLConfig*)malloc(sizeof(EGLConfig)*numConfigs);
if (eglChooseConfig(dpy, attrs, configs, numConfigs, &n) == EGL_FALSE) {
free(configs);
return BAD_VALUE;
}
int i;
EGLConfig config = NULL;
for (i=0 ; i<n ; i++) {
EGLint nativeVisualId = 0;
eglGetConfigAttrib(dpy, configs[i], EGL_NATIVE_VISUAL_ID, &nativeVisualId);
if (nativeVisualId>0 && format == nativeVisualId) {
config = configs[i];
break;
}
}
free(configs);
if (i<n) {
*outConfig = config;
return NO_ERROR;
}
return NAME_NOT_FOUND;
}
软件实现库libGLES_android.so调用libpixelflinger.so来进行底层的绘制操作。
EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list,
EGLConfig *configs, EGLint config_size,
EGLint *num_config)
{
。。。
for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) {
egl_connection_t* const cnx = &gEGLImpl[i];
if (cnx->dso) {
if (cnx->egl.eglChooseConfig(
dp->disp[i].dpy, attrib_list, configs, config_size, &n)) {
if (configs) {
// now we need to convert these client EGLConfig to our
// internal EGLConfig format.
// This is done in O(n Log(n)) time.
for (int j=0 ; j<n ; j++) {
egl_config_t key(i, configs[j]);
intptr_t index = binarySearch<egl_config_t>(
dp->configs, 0, dp->numTotalConfigs, key);
if (index >= 0) {
configs[j] = EGLConfig(index);
} else {
return setError(EGL_BAD_CONFIG, EGL_FALSE);
}
}
configs += n;
config_size -= n;
}
*num_config += n;
res = EGL_TRUE;
}
}
}
同一个dpy可能支持两种实现,gEGLImpl[IMPL_SOFTWARE],gEGLImpl[IMPL_HARDWARE]
分别查询这两种实现支持的config,硬件优先
。。。
}