android opengl函数库之间的关系

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表调用相应的程序,这个表通过
getGlThreadSpecific拿到,表中的函数指针是libEGL.so中初始化的。

软件的opengl实现库为libGLES_android.so,其中目前实现了egl和opengl1.1
硬件的通常对应三个文件,如libEGL_adreno200.so,libGLESv1_CM_adreno200.so,libGLESv2_adreno200.so

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,硬件优先

。。。



你可能感兴趣的:(android,api,session,null,hook)