OpenGL实现路径:

frameworks/native/opengl/libs/Android.mk

该makefile里面会编译出libEGL libGLESv1_CM 以及 libGLESv2

这里Android是已经实现了一套opengl的, 具体实现接口在: frameworks/native/opengl/libs/EGL/egl_entries.in

在这里面包含很多常见的opengl接口:

EGL_ENTRY(EGLDisplay, eglGetDisplay, NativeDisplayType)
EGL_ENTRY(EGLBoolean, eglInitialize, EGLDisplay, EGLint*, EGLint*)
EGL_ENTRY(EGLBoolean, eglTerminate, EGLDisplay)
EGL_ENTRY(EGLBoolean, eglGetConfigs, EGLDisplay, EGLConfig*, EGLint, EGLint*)
EGL_ENTRY(EGLBoolean, eglChooseConfig, EGLDisplay, const EGLint *, EGLConfig *, EGLint, EGLint *)

.........

该路径下Loader.cpp是加载具体opengl实现的逻辑:

1. 读取配置system/lib/egl/egl.cfg, 配置如下:

#0 0 android

0 1 mali

因此变量dpy=0, impl = 1, tag = mali, 默认也可能是dpy=0, impl = 0, tag = android。


2. 根据第一步的tag加载相应的库,如果tag是android则加载驱动:

如下代码优先加载libGLES, 如果使用Android原生实现库加载libGLES_android, 厂家也可以具体实现

if (tag) {
dso = load_driver("GLES", tag, cnx, EGL | GLESv1_CM | GLESv2);
if (dso) {
hnd = new driver_t(dso);
} else {
// Always load EGL first
dso = load_driver("EGL", tag, cnx, EGL);
if (dso) {
hnd = new driver_t(dso);
// TODO: make this more automated
hnd->set( load_driver("GLESv1_CM", tag, cnx, GLESv1_CM), GLESv1_CM );
hnd->set( load_driver("GLESv2", tag, cnx, GLESv2), GLESv2 );
}
}
}

libGLES_android实现path: frameworks/native/opengl/libagl/Android.mk


3. 通过dlsym读取库实现函数填充connection->egl, gHooks[egl_connection_t::GLESv1_INDEX], gHooks[egl_connection_t::GLESv2_INDEX]


这部分由第一次eglGetDisplay, eglGetDisplay实现EGL/egl.cpp 头文件EGL/egl.h


在eglGetDisplay中会去初始化驱动,最终调用到egl_init_drivers_locked函数中。这个函数的主要内容如下

EGLBoolean egl_init_drivers_locked()

{

if (sEarlyInitState) {

// initialized by static ctor. should be set here.

return EGL_FALSE;

}

// get our driver loader

Loader& loader(Loader::getInstance());

// dynamically load all our EGL implementations for all displays

// and retrieve the corresponding EGLDisplay

// if that fails, don't use this driver.

// TODO: currently we only deal with EGL_DEFAULT_DISPLAY

egl_connection_t* cnx;

egl_display_t* d = &gDisplay[0];

cnx = &gEGLImpl[IMPL_SOFTWARE];

if (cnx->dso == 0) {

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

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

cnx->dso = loader.open(EGL_DEFAULT_DISPLAY, 0, cnx);

if (cnx->dso) {

EGLDisplay dpy = cnx->egl.eglGetDisplay(EGL_DEFAULT_DISPLAY);

LOGE_IF(dpy==EGL_NO_DISPLAY, "No EGLDisplay for software EGL!");

d->disp[IMPL_SOFTWARE].dpy = dpy;

if (dpy == EGL_NO_DISPLAY) {

loader.close(cnx->dso);

cnx->dso = NULL;

}

}

}

cnx = &gEGLImpl[IMPL_HARDWARE];

if (cnx->dso == 0) {

char value[PROPERTY_VALUE_MAX];

property_get("debug.egl.hw", value, "1");

if (atoi(value) != 0) {

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

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

cnx->dso = loader.open(EGL_DEFAULT_DISPLAY, 1, cnx);

if (cnx->dso) {

EGLDisplay dpy = cnx->egl.eglGetDisplay(EGL_DEFAULT_DISPLAY);

LOGE_IF(dpy==EGL_NO_DISPLAY, "No EGLDisplay for hardware EGL!");

d->disp[IMPL_HARDWARE].dpy = dpy;

if (dpy == EGL_NO_DISPLAY) {

loader.close(cnx->dso);

cnx->dso = NULL;

}

}

} else {

LOGD("3D hardware acceleration is disabled");

}

}

if (!gEGLImpl[IMPL_SOFTWARE].dso && !gEGLImpl[IMPL_HARDWARE].dso) {

return EGL_FALSE;

}

return EGL_TRUE;

}

egl_init_drivers_locked函数主要的工作就是填充gEGLImp数组变量,这个变量是egl_connection_t类型。还有一个工作就是填充gDisplay数组(只有一个元素)的disp[IMPL_HARDWARE].dpy以及disp[IMPLSOFTWAREWARE].dpy,填充的来源来自gEGLImpl【soft or hard】.egl.eglGetDisplay(EGL_DEFAULT_DISPLAY);

在Loader.cpp中的Loader::open中会加载对应的硬件和软件加速的驱动(动态链接库)。

软件的对应的是/system/lib/egl/libEGL_android.so,没有默认的硬件so,因此在硬件加速时,返回值hnd会指向NULL,在需要硬件加速时这个动态链接库需要进行实现。

LoadDriver函数会根据其第三个参数,决定加载egl/gles,glesv1_cm,glesv2驱动。






更多相关文章

  1. static 和 visibility hidden 的区别
  2. [Android从头再来]Android(安卓)JNI相关开发
  3. android分包原理--MultiDex
  4. Android资源加载机制
  5. Android(安卓)GUI更新过程
  6. 【Android(安卓)自定义控件】自定义View相关知识总结
  7. 自定义加载动画的两种实现方式
  8. Android(安卓)反汇编Smali语言中插入log打印
  9. Android(安卓)Studio加载第三方jar包,出现包重复加载的问题解决(:a

随机推荐

  1. 部署MySQL延迟从库的好处小结
  2. Mysql SSH隧道连接使用的基本步骤
  3. SQL Server 完整备份遇到的一个不常见的
  4. mysql-8.0.15-winx64 使用zip包进行安装
  5. MySQL8.x msi版安装教程图文详解
  6. MySQL中的行级锁定示例详解
  7. Android(安卓)mk编译OkHttp3
  8. Ubuntu下 下载Android(安卓)源码(来自官网
  9. android 读取指定路径数据库文件
  10. Android(安卓)transformClassesWithDexFo