Android OpenGL ES 分析与实践(6)

来源:互联网 发布:如何测试网络稳定性 编辑:程序博客网 时间:2024/06/05 05:08

egl_connection_t的第二个变量是一个指针数组,类型是gl_hooks_t,从名字可以看出,它指向的是一组函数指针。跟踪一下

struct gl_hooks_t {

    struct gl_t {

        #include "entries.in"

    } gl;

    struct gl_ext_t {

        void (*extensions[MAX_NUMBER_OF_GL_EXTENSIONS])(void);

    } ext;

};

这个entries.ini文件里全部是函数的一些原型。。

证明了猜想。

 

        cnx->hooks[GLESv1_INDEX] = &gHooks[GLESv1_INDEX][IMPL_SOFTWARE];

        cnx->hooks[GLESv2_INDEX] = &gHooks[GLESv2_INDEX][IMPL_SOFTWARE];

这里将egl_connecttion_t变量指向了全局的gHooks,这些函数指针从哪里赋值的呢?跟踪发现,是在LoadDriver时,也是从

libGLES_android.so中查找出GLESV1_CM和GLESV2两组函数来对其进行了赋值操作。

 

major和minor是版本号。

最后一个变量egl_t egl。这个变量非常重要。在load_driver中可以看到它的身影(通过loader::open间接调用的)。

 

struct egl_t {

    #include "EGL/egl_entries.in"

};

egl_t中也是一组函数指针,其中包含了OpenGL ES中底层的实现。所以如果要实现硬件加速的话,这里面的函数都要实现。

 

 

 egl_t* egl = &cnx->egl;

__eglMustCastToProperFunctionPointerType*curr =

(__eglMustCastToProperFunctionPointerType*)egl;

char const *const *api = egl_names;

while (*api)

{

     char const * name = *api;

     __eglMustCastToProperFunctionPointerTypef =

         (__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++;

}

上面的这些语句完成了将驱动(libGLES_android.so)中的函数地址赋值给了cnx->egl指向的egl_t结构。因此有了这些操作,下面

就可以通过egl_connection_t::egl来访问EGL中的一些底层的函数了,比如初始化等的操作。

 

要实现硬件加速,需要实现的是与libGLES_android.so对应的那些函数。android会自动完成对其的加载、初始化、调用。

 

 

上面的一大部分功能都是在loader::open中进行调用的,回到egl_init_drivers_locked函数中。

其在调用了loader::open函数完成了对libGLES_android.so中的库进行加载的操作之后,真正开始 初始化操作了,所以说上面的一大部分操作,其实都是一些预初始化,真正的初始化操作还没有开始。。。。

 

真正的初始化操作来自这里EGLDisplay dpy = cnx->egl.eglGetDisplay(EGL_DEFAULT_DISPLAY);

通过刚才的分析,我们很容易知道,这个egl.eglGetDisplay函数到底要去哪里找。有bet。

我们上面打印出了

*api=eglGetDisplay

curr=ac708a60,it's address is acc931a5

这个东东在libGLES_android.so的源码里。

 

eglGetDisplay在内部的实现并不是通过返回值的方式进行传递的,而是用的全局变量。

 

eglGetDisplay完成的事情主要有,加载真正的OpenGL ES 的动态链接库文件,里面包含各种openGL的操作,这个函数库在libGLES_andorid.so中,加载动态链接库之后,会将其中的一些函数指针的值传递到全局的gEGLImpl中,通过这个全局的结构体,可以访问libGLES_android.so中的所有的函数。

 

下面分析应用程序中调用eglInitialize函数,会完成的操作。

eglInitialize

 

在这个函数中,主要调用了libGLES_android中的eglIniitalize函数,eglGetConfigs函数,获取配置信息。

3.5 使用OpenGL ES硬件加速功能的方法

使用硬件加速功能的OpenGL ES的方法。

1.修改Loader.cpp文件里的Loader::loader函数,添加gConfig.add( entry_t(0, 1, "mmoid") );或者修改egl.cfg文件。此文件位于/system/lib/egl/下,如果不存在,可以自己动手新建。格式是“dpy impl tag”比如自己添加的硬件加速库是libGLES_mmoid.so,则需要在此文件里这样编写

0 1 mmoid

修改后腰重启才可生效。

现在已经可以使用硬件加速功能了。