Android是怎样调用硬件加速的
[描述]
如果处理器只有2D硬件加速而没有3D硬件加速,则可以利用opengl中的libagl,
实现封装在libagl里的copybit,因为相对3D API来说,这个模块的封装google
基本是做好的,只要去实现一个copybit HAL即可;
如果处理器2D/3D硬件加速均有,那么可以丢开 copybit,去实现openGL ES
2D/3D API 的加速功能。
[Android是怎样加载软件/硬件加速库的]
1. 全局变量gEGLImpl: 定义egl&gles的API的指针
egl_connection_t gEGLImpl[IMPL_NUM_IMPLEMENTATIONS];
enum {
IMPL_HARDWARE = 0,
IMPL_SOFTWARE,
IMPL_NUM_IMPLEMENTATIONS
};
具体数据结构参看附录。
2. 初始化全局变量gEGLImpl
Code:egl_init_drivers_locked()<frameworks/base/opengl/libs/EGL/egl.cpp>
egl_init_drivers_locked()函数主要的工作就是填充gEGLImp数组变量
该函数调用Loader.cpp中的Loader::open()加载对应的硬件和软件加速的驱动(动态链接库).
a. 加载libGLES_android.so填充gEGLImpl[IMPL_SOFTWARE];
b. 加载libGLES_HWxxxxx.so填充gEGLImpl[IMPL_HARDWARE];
注:配置文件/system/lib/egl/egl.cfg中列出了系统中的软件/硬件减速库
格式: dpy impl tag
0 0 android
0 1 HWxxxxx
[2D硬件加速]
frameworks/base/opengl/libagl/egl.cpp 文件中利用hardware/libhardware/hardware.c
文件中定义的hw_get_module()函数,该函数判断获得的系统属性是否在variant_keys[]数组中定义
通过load()函数加载相应的硬件模块;否则加载default硬件模块。
因此需要研究libagl,根据需要实现相应的copybit硬件模块。
注:
libGLES_android.so为编译frameworks/base/opengl/libagl/目录而生成的,其专门有一个
copybit.cpp文件对copybit模块进一步封装。
libagl中通过在frameworks/base/opengl/libagl/Android.mk文件中定义:
LIBAGL_USE_GRALLOC_COPYBITS := 1
来加载copybit模块;如果未定义LIBAGL_USE_GRALLOC_COPYBITS,则通过软件的方式而不使用
copybit 模块来达到 2D 硬件加速。
[2D/3D硬件加速]
需研究opengles, 并实现
/system/lib/egl/libGLES_HWxxxxx.so
或者
/system/lib/egl/libEGL_HWxxxxx.so
/system/lib/egl/libGLESv1_CM_HWxxxxx.so
/system/lib/egl/libGLESv2_HWxxxxx.so
来提供 openGL ES 2D/3D 硬件加速 API 。
[应用是怎样使用OpenGLES硬件加速的]
1.应用调用eglChooseConfig时,libs/EGL/egl.cpp::eglChooseConfig根据参数选择config时,
调用顺序为:
gEGLImpl[IMPL_HARDWARE].egl.eglChooseConfig(...)
gEGLImpl[IMPL_SOFTWARE].egl.eglChooseConfig(...)
原因: IMPL_HARDWARE=0; IMPL_SOFTWARE=1
参看:
enum {
IMPL_HARDWARE = 0,
IMPL_SOFTWARE,
IMPL_NUM_IMPLEMENTATIONS
};
2. 创建Surface和Context时, libs/EGL/egl.cpp是根据传入参数config来判断是调用软件还是
硬件加速API的, 而根据步骤1优先选择的缉硬件的config, 故创建Surface和Context是使用的
也是硬件加速的API。
[附录]:
struct egl_connection_t
{
void * dso;
gl_hooks_t * hooks[2];
EGLint major;
EGLint minor;
egl_t egl;
};
struct egl_t {
#include "EGL/egl_entries.in"
};
struct gl_hooks_t {
struct gl_t {
#include "entries.in"
} gl;
struct gl_ext_t {
void (*extensions[MAX_NUMBER_OF_GL_EXTENSIONS])(void);
} ext;
};