Android 图形系统加速学习系列(2)

#define CALL_GL_API_RETURN(_api, ...) \
        CALL_GL_API(_api, __VA_ARGS__) \
        return 0; // placate gcc's warnings. never reached.


CALL_GL_API这个带参数的宏。它的意思是获取TLS_SLOT_OPENGL_API的TLS,如果它的值不是NULL,就跳到相应的OpenGL ES API的地址去执行。这个地方为什么会跳过去呢??因为从线程局部存储保存的线程指针,指向了一个gl_hooks_t指针,而这个指针指向的结构体里的成员已经在EGL中被初始化为了libGLES_android.so里的函数地址了。所以就可以跳过去了。

那么在哪里初始化gl_hooks_t指针的呢? (frameworks\base\opengl\libs\EGL\Loader.cpp)

FILE* cfg = fopen("/system/lib/egl/egl.cfg", "r");
    if (cfg == NULL) {  // 如果找不到这个配置则默认加载软件3D库即 libGLES_android.so
        // default config
        LOGD("egl.cfg not found, using default config");
        gConfig.add( entry_t(0, 0, "android") );
    } 

否则根据配置文件加载硬件3D库,egl.cfg 文件格式是“dpy impl tag”比如自己添加的硬件加速库是libGLES_mali.so,则需要在此文件里这样编写
   0 1 mali

修改后要重启才可生效。

加载就是利用dlopen、dlsym加载并赋值:

void* dso = dlopen(driver_absolute_path, RTLD_NOW | RTLD_LOCAL);

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++;
        }

char const * const gl_names[] = {
    #include "entries.in"
    NULL
  };

char const * const egl_names[] = {
    #include "egl_entries.in"
    NULL
};

这里面包含的函数头文件在:gl2_api.in 及 gl_api.in 中对应于不同的版本,对应用C头文件接口是: include/RGL/egl.h 及

include\GLES\中的gl.h和glext.h,这些接口供外部调用OpenGL本库所使用接口,这些接口基本上和OpenGL标准接口一致。

#include <EGL/egl.h>
 #include <GLES/gl.h>

#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>

插一句如何知道哪些OpenGL函数没有实现呢?

在init_api函数添加打印即可知道哪些函数没有实现:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wyjwds.html